MissionChief Command Nexus

Unified MissionChief UK toolkit for mission dispatch, unit naming, station naming and trained-personnel assignment.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         MissionChief Command Nexus
// @namespace    https://github.com/Team-Killing-Bastards/MissionChief-Command-Nexus
// @version      1.0.21
// @description  Unified MissionChief UK toolkit for mission dispatch, unit naming, station naming and trained-personnel assignment.
// @author       MartyBlyth
// @license      MIT
// @homepageURL  https://github.com/Team-Killing-Bastards/MissionChief-Command-Nexus
// @supportURL   https://github.com/Team-Killing-Bastards/MissionChief-Command-Nexus/issues
// @match        https://www.missionchief.co.uk/*
// @match        https://police.missionchief.co.uk/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    // One combined installation guard. Each retained module also keeps its
    // original guard, so enabling an old standalone copy cannot initialise a
    // second UI or a second automation engine in the same page context.
    if (window.__MC_COMPLETE_TOOLS_MERGED_V10668_V428__) return;
    window.__MC_COMPLETE_TOOLS_MERGED_V10668_V428__ = true;

    // Runtime isolation preserves the behaviour of two standalone userscripts:
    // a startup fault in one module is reported without preventing the other
    // independent module from loading.
    try {
        /* ==================================================================
         * MODULE 1: UNIT, STATION & PERSONNEL TOOLS V4.2.8
         * Original source retained below, excluding only its metadata block.
         * ================================================================== */
(function () {
    'use strict';

    if (window.__MC_NAMING_TOOLS_V428__) return;
    window.__MC_NAMING_TOOLS_V428__ = true;

    const UNIT_VERSION = '3.3.7';
    const STATION_VERSION = '1.3.3';
    const PERSONNEL_VERSION = '1.3.2';
    const PERSONNEL_TRAINING_CODE = 'critical_care';
    const PERSONNEL_TRAINING_LABEL = 'Critical Care';
    const PERSONNEL_TARGET_VEHICLE_TYPE_ID = '5';
    const PERSONNEL_TARGET_VEHICLE_LABEL = 'Ambulance';
    const PERSONNEL_TARGET_PER_VEHICLE = 1;
    const PERSONNEL_REQUEST_GAP_MS = 650;
    const PERSONNEL_STATION_GAP_MS = 900;
    const ACTIVE_TAB_STORAGE_KEY = 'mcNamingToolsActiveTab_v32';
    const COLLAPSED_STORAGE_KEY = 'mcNamingToolsCollapsed_v36';
    const PERSONNEL_STATION_REPORT_VISIBLE_KEY = 'mcPersonnelStationReportVisible_v407';
    const PERSONNEL_OVERALL_REPORT_VISIBLE_KEY = 'mcPersonnelOverallReportVisible_v407';
    const PERSONNEL_SERVICE_STORAGE_KEY = 'mcPersonnelService_v410';
    const PERSONNEL_PROFILE_STORAGE_KEY = 'mcPersonnelProfile_v410';
    const PERSONNEL_UNITS_REQUIRED_STORAGE_KEY = 'mcPersonnelUnitsRequired_v423';
    const PERSONNEL_TRAINING_REGISTRY_STORAGE_KEY =
        'mcPersonnelVehicleTrainingRegistry_v1';
    const PERSONNEL_TRAINING_REGISTRY_SCHEMA_VERSION = 1;
    const TOOL_LOG_MAX_LINES = 400;
    const TOOL_LOG_TRIM_BUFFER = 40;
    const PERSONNEL_TRAINING_REGISTRY_MAX_VEHICLES = 5000;
    const PERSONNEL_TRAINING_REGISTRY_MAX_AGE_MS = 180 * 24 * 60 * 60 * 1000;
    const PERSONNEL_TRAINING_REGISTRY_QUOTA_RETRY_MAX_VEHICLES = 2500;
    const PERSONNEL_TRAINING_REGISTRY_FLUSH_DELAY_MS = 1400;
    const PERSONNEL_TRAINING_REGISTRY_PRUNE_INTERVAL_MS = 6 * 60 * 60 * 1000;
    const TOOL_LIFECYCLE_CLEANUPS = new Set();
    const TOOL_LOG_SCROLL_FRAMES = new Map();
    const TOOL_UI_ELEMENT_CACHE = new Map();
    const PERSONNEL_ASSIGNMENT_INDEX_CACHE = new WeakMap();
    const PERSONNEL_TRAINING_SET_CACHE = new WeakMap();
    const PERSONNEL_VISIBLE_TRAINING_COUNTS_CACHE = new WeakMap();
    const PERSONNEL_REPORT_BLOCK_CACHE = new WeakMap();
    const PERSONNEL_STATION_LINK_BY_HREF = new Map();
    const PERSONNEL_START_OPTION_BY_HREF = new Map();
    const PERSONNEL_HIGHLIGHTED_STATION_LINKS = new Set();
    let TOOL_LIFECYCLE_CLEANED = false;
    let PERSONNEL_TRAINING_REGISTRY_CACHE = null;
    let PERSONNEL_TRAINING_REGISTRY_DIRTY = false;
    let PERSONNEL_TRAINING_REGISTRY_FLUSH_TIMER = null;
    let PERSONNEL_TRAINING_REGISTRY_PENDING_EVENT = null;
    let PERSONNEL_SHORTFALL_CACHE_SIZE = -1;
    let PERSONNEL_SHORTFALL_CACHE = [];

    const makeServicePreviewProfile = (id, label, serviceLabel) => ({
        id,
        label,
        vehicle: `Mapped ${serviceLabel} vehicle(s)`,
        requirement: `${label} on mapped vehicle seats`,
        policy: `UI preview: ${label} has been added from the supplied ${serviceLabel} training list. Vehicle mapping and required seat counts still need confirmation before assignment can be enabled.`,
        live: false,
        stationTypes: []
    });

    const makePoliceRule = ({
        id,
        label,
        vehicleTypeIds,
        vehicleLabel,
        target,
        trainingAll,
        trainingLabel,
        preferWithout = [],
        sharedVehiclePool = false
    }) => Object.freeze({
        id,
        label,
        vehicleTypeIds: vehicleTypeIds.map(String),
        vehicleLabel,
        target: Number(target),
        trainingAll: trainingAll.map(String),
        trainingLabel,
        preferWithout: preferWithout.map(String),
        sharedVehiclePool: Boolean(sharedVehiclePool)
    });

    const POLICE_TRAINING_LABELS =
        Object.freeze({
            level_1_public_order:
                'Level 1 Public Order',
            level_2_public_order:
                'Level 2 Public Order',
            police_sergeant:
                'Police Sergeant',
            police_medic:
                'Police Medic',
            police_inspector:
                'Police Inspector',
            traffic_police:
                'Roads Policing',
            swat:
                'Firearms',
            police_horse:
                'Mounted Officer',
            k9:
                'Dog Handler',
            drone:
                'Drone Operator',
            search_and_rescue:
                'Police Search Advisor',
            polizeihubschrauber:
                'Police Aviation',
            railway_police_command:
                'Mobile Operations Management',
            railway_police:
                'Railway Police Officer',
            bomb_disposal_command:
                'EOD Commander',
            bomb_disposal:
                'Bomb Disposal',
            bomb_disposal_diver:
                'Marine Bomb Disposal',
            elw2:
                'Level 1 Incident Commander Training',
            gw_gefahrgut:
                'HazMat Unit',
            railway_fire:
                'Railway Fire'
        });

    const POLICE_RULES = Object.freeze({
        publicOrderLevel1: makePoliceRule({
            id:
                'police_public_order_level_1',
            label:
                'Level 1 Public Order',
            vehicleTypeIds: [
                '8'
            ],
            vehicleLabel:
                'Incident Response Vehicle',
            target:
                2,
            trainingAll: [
                'level_1_public_order'
            ],
            trainingLabel:
                'Level 1 Public Order',
            sharedVehiclePool:
                true
        }),
        publicOrderLevel2: makePoliceRule({
            id:
                'police_public_order_level_2',
            label:
                'Level 2 Public Order',
            vehicleTypeIds: [
                '8'
            ],
            vehicleLabel:
                'Incident Response Vehicle',
            target:
                2,
            trainingAll: [
                'level_2_public_order'
            ],
            trainingLabel:
                'Level 2 Public Order',
            sharedVehiclePool:
                true
        }),
        publicOrderSergeant: makePoliceRule({
            id:
                'police_public_order_sergeant',
            label:
                'Police Sergeant',
            vehicleTypeIds: [
                '8'
            ],
            vehicleLabel:
                'Incident Response Vehicle',
            target:
                2,
            trainingAll: [
                'police_sergeant'
            ],
            trainingLabel:
                'Police Sergeant',
            sharedVehiclePool:
                true
        }),
        publicOrderMedic: makePoliceRule({
            id:
                'police_public_order_medic',
            label:
                'Police Medic',
            vehicleTypeIds: [
                '8'
            ],
            vehicleLabel:
                'Incident Response Vehicle',
            target:
                2,
            trainingAll: [
                'police_medic'
            ],
            trainingLabel:
                'Police Medic',
            sharedVehiclePool:
                true
        }),
        publicOrderCombined: makePoliceRule({
            id: 'police_public_order_combined',
            label: 'Public Order L1 + L2 + Sergeant + Police Medic',
            vehicleTypeIds: ['8'],
            vehicleLabel: 'Incident Response Vehicle',
            target: 2,
            trainingAll: ['level_1_public_order', 'level_2_public_order', 'police_sergeant', 'police_medic'],
            trainingLabel: 'Level 1 + Level 2 + Sergeant + Police Medic',
            sharedVehiclePool: true
        }),
        inspector: makePoliceRule({
            id: 'police_inspector',
            label: 'Police Inspector',
            vehicleTypeIds: ['8'],
            vehicleLabel: 'Incident Response Vehicle',
            target: 2,
            trainingAll: ['police_inspector'],
            trainingLabel: 'Police Inspector',
            sharedVehiclePool: true
        }),
        roads: makePoliceRule({
            id: 'police_roads_firearms',
            label: 'Roads Policing + Firearms',
            vehicleTypeIds: ['25'],
            vehicleLabel: 'Armed Traffic Car',
            target: 2,
            trainingAll: ['traffic_police', 'swat'],
            trainingLabel: 'Roads Policing + Firearms'
        }),
        firearms: makePoliceRule({
            id: 'police_mrav_firearms',
            label: 'Firearms',
            vehicleTypeIds: ['56'],
            vehicleLabel: 'Multi-Role Armoured Vehicle',
            target: 6,
            trainingAll: ['swat'],
            trainingLabel: 'Firearms',
            preferWithout: ['traffic_police']
        }),
        mounted: makePoliceRule({
            id: 'police_mounted',
            label: 'Mounted Officers',
            vehicleTypeIds: ['55'],
            vehicleLabel: 'Mounted Unit',
            target: 1,
            trainingAll: ['police_horse'],
            trainingLabel: 'Mounted Officers'
        }),
        dog: makePoliceRule({
            id: 'police_dog',
            label: 'Dog handling',
            vehicleTypeIds: ['12'],
            vehicleLabel: 'Dog Support Unit',
            target: 1,
            trainingAll: ['k9'],
            trainingLabel: 'Dog handling'
        }),
        searchAdvisor: makePoliceRule({
            id: 'police_drone_search_advisor',
            label: 'Drone Operator + Police Search Advisor',
            vehicleTypeIds: ['91'],
            vehicleLabel: 'Police Drone Vehicle',
            target: 2,
            trainingAll: ['drone', 'search_and_rescue'],
            trainingLabel: 'Drone Operator + Police Search Advisor',
            sharedVehiclePool: true
        }),
        drone: makePoliceRule({
            id: 'police_drone',
            label: 'Drone Operator',
            vehicleTypeIds: ['91'],
            vehicleLabel: 'Police Drone Vehicle',
            target: 2,
            trainingAll: ['drone'],
            trainingLabel: 'Drone Operator',
            preferWithout: ['search_and_rescue'],
            sharedVehiclePool: true
        }),
        aviation: makePoliceRule({
            id: 'police_aviation',
            label: 'Police aviation',
            vehicleTypeIds: ['11'],
            vehicleLabel: 'Police Helicopter',
            target: 3,
            trainingAll: ['polizeihubschrauber'],
            trainingLabel: 'Police aviation'
        }),
        mobileOperations: makePoliceRule({
            id: 'police_mobile_operations',
            label: 'Mobile Operations Management',
            vehicleTypeIds: ['108'],
            vehicleLabel: 'EIU',
            target: 2,
            trainingAll: ['railway_police_command'],
            trainingLabel: 'Mobile Operations Manager'
        }),
        railway: makePoliceRule({
            id: 'police_railway',
            label: 'Railway Police Officer',
            vehicleTypeIds: ['8'],
            vehicleLabel: 'Railway Policing IRV',
            target: 2,
            trainingAll: ['railway_police'],
            trainingLabel: 'Railway Police Officer',
            preferWithout: ['railway_police_command'],
            sharedVehiclePool: true
        }),
        eodCommander: makePoliceRule({
            id: 'police_eod_commander',
            label: 'EOD Commander',
            vehicleTypeIds: ['109'],
            vehicleLabel: 'EOD Commander Vehicle',
            target: 2,
            trainingAll: ['bomb_disposal_command'],
            trainingLabel: 'EOD Commander'
        }),
        eodResponse: makePoliceRule({
            id: 'police_eod_response',
            label: 'Bomb Disposal',
            vehicleTypeIds: ['110'],
            vehicleLabel: 'EOD Response Vehicle',
            target: 4,
            trainingAll: ['bomb_disposal'],
            trainingLabel: 'Bomb Disposal',
            preferWithout: ['bomb_disposal_command']
        }),
        eodMedium: makePoliceRule({
            id: 'police_eod_medium',
            label: 'Bomb Disposal',
            vehicleTypeIds: ['111'],
            vehicleLabel: 'EOD Medium Equipment Van',
            target: 3,
            trainingAll: ['bomb_disposal'],
            trainingLabel: 'Bomb Disposal',
            preferWithout: ['bomb_disposal_command']
        }),
        eodHeavy: makePoliceRule({
            id: 'police_eod_heavy',
            label: 'Bomb Disposal',
            vehicleTypeIds: ['112'],
            vehicleLabel: 'EOD Heavy Equipment Vehicle',
            target: 2,
            trainingAll: ['bomb_disposal'],
            trainingLabel: 'Bomb Disposal',
            preferWithout: ['bomb_disposal_command']
        }),
        marineResponse: makePoliceRule({
            id: 'police_marine_eod_response',
            label: 'Marine Bomb Disposal',
            vehicleTypeIds: ['113'],
            vehicleLabel: 'Marine EOD Response Vehicle',
            target: 4,
            trainingAll: ['bomb_disposal_diver'],
            trainingLabel: 'Marine Bomb Disposal'
        }),
        marineEquipment: makePoliceRule({
            id: 'police_marine_eod_equipment',
            label: 'Marine Bomb Disposal',
            vehicleTypeIds: ['114'],
            vehicleLabel: 'Marine EOD Equipment Van',
            target: 3,
            trainingAll: ['bomb_disposal_diver'],
            trainingLabel: 'Marine Bomb Disposal'
        })
    });

    const FIRE_RULES = Object.freeze({
        incidentCommand: makePoliceRule({
            id: 'fire_level_1_incident_command', label: 'Level 1 Incident Commander Training',
            vehicleTypeIds: ['15'], vehicleLabel: 'Incident Command and Control Unit', target: 3,
            trainingAll: ['elw2'], trainingLabel: 'Level 1 Incident Commander Training'
        }),
        hazmatOsu: makePoliceRule({
            id: 'fire_hazmat_osu', label: 'HazMat Unit',
            vehicleTypeIds: ['39'], vehicleLabel: 'Operational Support Unit', target: 3,
            trainingAll: ['gw_gefahrgut'], trainingLabel: 'HazMat Unit'
        }),
        railway: makePoliceRule({
            id: 'fire_railway', label: 'Railway Fire',
            vehicleTypeIds: ['107'], vehicleLabel: 'RRU', target: 2,
            trainingAll: ['railway_fire'], trainingLabel: 'Railway Fire'
        })
    });

    const POLICE_ALL_RULES = Object.freeze([
        POLICE_RULES.eodCommander,
        POLICE_RULES.searchAdvisor,
        POLICE_RULES.mobileOperations,
        POLICE_RULES.roads,
        POLICE_RULES.inspector,
        POLICE_RULES.railway,
        POLICE_RULES.publicOrderCombined,
        POLICE_RULES.aviation,
        POLICE_RULES.marineResponse,
        POLICE_RULES.marineEquipment,
        POLICE_RULES.eodResponse,
        POLICE_RULES.eodMedium,
        POLICE_RULES.eodHeavy,
        POLICE_RULES.firearms,
        POLICE_RULES.mounted,
        POLICE_RULES.dog,
        POLICE_RULES.drone
    ]);

    const livePoliceProfile = (id, label, vehicle, requirement, policy, rules, stationTypes = ['POLICE']) => ({
        id,
        label,
        vehicle,
        requirement,
        policy,
        live: true,
        engine: 'police',
        stationTypes,
        rules
    });

    const liveFireProfile = (id, label, vehicle, requirement, policy, rules) => ({
        id, label, vehicle, requirement, policy, live: true,
        engine: 'police', stationTypes: ['FIRE'], rules
    });

    // Medical specialist profiles stay in UI preview until their exact vehicle,
    // capacity and training-code mappings have been captured and verified. Critical
    // Care remains the proven Medical live engine and is exclusive to normal Ambulances.
    const PERSONNEL_SERVICE_DEFINITIONS = {
        medical: {
            label: 'Medical',
            icon: '🚑',
            profiles: [
                {
                    id: 'critical_care',
                    label: 'Critical Care',
                    vehicle: 'Normal Ambulance',
                    requirement: '1 Critical Care-trained staff per Ambulance',
                    policy: 'LIVE ENGINE: Critical Care is used only for normal Ambulances. Existing assignments are preserved and vehicles are safely topped up to 1 trained staff.',
                    live: true,
                    engine: 'medical-critical-care',
                    stationTypes: ['AMBULANCE']
                },
                {
                    id: 'ambulance_officer',
                    label: 'Ambulance Officer',
                    vehicle: 'Ambulance Officer vehicle',
                    requirement: 'Ambulance Officer-trained staff',
                    policy: 'UI preview: the exact vehicle capacity and training mapping still require a verified assignment-page capture before this profile can safely go live.',
                    live: false,
                    stationTypes: ['AMBULANCE']
                },
                {
                    id: 'hart',
                    label: 'HART Training',
                    vehicle: 'PRV / SRV and mapped HART vehicles',
                    requirement: 'HART-trained staff',
                    policy: 'UI preview: HART vehicle-by-vehicle staffing rules still require verified assignment-page captures.',
                    live: false,
                    stationTypes: ['AMBULANCE']
                },
                {
                    id: 'midwifery',
                    label: 'Midwifery Training',
                    vehicle: 'Community Midwife vehicle',
                    requirement: 'Midwifery-trained staff',
                    policy: 'UI preview: the Community Midwife vehicle type, capacity and exact training code are not yet verified.',
                    live: false,
                    stationTypes: ['AMBULANCE']
                },
                {
                    id: 'sort',
                    label: 'SORT Training',
                    vehicle: 'Mass Casualty / CBRN medical vehicles',
                    requirement: 'SORT-trained staff',
                    policy: 'UI preview: the exact SORT vehicle family, capacities and training code still need verified assignment pages.',
                    live: false,
                    stationTypes: ['AMBULANCE']
                },
                {
                    id: 'specialist_paramedic',
                    label: 'Specialist Paramedic Training',
                    vehicle: 'Specialist Paramedic RRV',
                    requirement: 'Specialist Paramedic-trained staff',
                    policy: 'UI preview: the Specialist Paramedic RRV vehicle capacity and exact training code still need verification.',
                    live: false,
                    stationTypes: ['AMBULANCE']
                },
                {
                    id: 'tactical_command',
                    label: 'Tactical Command Course',
                    vehicle: 'Ambulance command vehicles',
                    requirement: 'Tactical Command-trained staff',
                    policy: 'UI preview: command vehicle mappings, capacities and exact training code still need verification.',
                    live: false,
                    stationTypes: ['AMBULANCE']
                },
                {
                    id: 'all_medical',
                    label: 'Run all Medical profiles',
                    vehicle: 'All mapped medical vehicle groups',
                    requirement: 'Specialist profiles first; Critical Care Ambulances last',
                    policy: 'UI preview: this batch option will be enabled only after every Medical specialist profile is individually verified and live.',
                    live: false,
                    stationTypes: ['AMBULANCE']
                }
            ]
        },
        fire: {
            label: 'Fire / Airfield',
            icon: '🚒✈️',
            profiles: [
                makeServicePreviewProfile('fire_aircraft_rescue', 'Aircraft Rescue and Firefighting', 'Fire'),
                makeServicePreviewProfile('fire_co_responder', 'Co-Responder Training', 'Fire'),
                makeServicePreviewProfile('fire_drone_operator', 'Drone Operator Training', 'Fire'),
                liveFireProfile('fire_hazmat', 'HazMat Unit', 'Operational Support Unit (OSU)', '3 HazMat-trained personnel per OSU', 'LIVE: fills each exact type-39 Fire OSU with 3 gw_gefahrgut-trained personnel. Type-7 HazMat Units are excluded.', [FIRE_RULES.hazmatOsu]),
                makeServicePreviewProfile('fire_high_volume_pump', 'High Volume Pump Training', 'Fire'),
                makeServicePreviewProfile('fire_lifeguard', 'Lifeguard Training', 'Fire'),
                liveFireProfile('fire_mobile_command', 'Level 1 Incident Commander Training', 'Incident Command and Control Unit (ICCU)', '3 Level 1 Incident Commanders per ICCU', "LIVE: fills each exact type-15 ICCU with 3 elw2-trained personnel while preserving its remaining seats.", [FIRE_RULES.incidentCommand]),
                liveFireProfile('fire_railway', 'Railway Fire', 'RRU', '2 Railway Fire-trained personnel per RRU', 'LIVE: fills each exact type-107 RRU to 2/2 with railway_fire-trained personnel.', [FIRE_RULES.railway]),
                {
                    id: 'all_fire',
                    label: 'Run all Fire / Airfield profiles',
                    vehicle: 'All mapped Fire and Airfield vehicle groups',
                    requirement: 'Process enabled Fire and Airfield profiles in priority order',
                    policy: 'Future batch option. Airfield training and vehicles are handled within Fire. It remains disabled until every Fire and Airfield profile has confirmed mappings.',
                    live: false,
                    stationTypes: ['FIRE', 'AIRFIELD']
                }
            ]
        },
        police: {
            label: 'Police',
            icon: '🚓',
            profiles: [
                livePoliceProfile('police_bomb_disposal', 'Bomb Disposal', 'EOD Response, Medium and Heavy vehicles', 'Fill each mapped EOD vehicle to its verified maximum with Bomb Disposal personnel', 'LIVE: EOD Commander vehicles are processed first by Run all Police, then Response 4/4, Medium 3/3 and Heavy 2/2. Existing assignments are preserved.', [POLICE_RULES.eodResponse, POLICE_RULES.eodMedium, POLICE_RULES.eodHeavy], ['EOD']),
                livePoliceProfile('police_dog_handling', 'Dog handling', 'Dog Support Unit', 'At least 1 Dog Handler per DSU', 'LIVE: safely meets the game-confirmed minimum of one Dog Handler per DSU without moving existing staff.', [POLICE_RULES.dog]),
                livePoliceProfile('police_drone_operator', 'Drone Operator Training', 'Police Drone Vehicle', '2 Drone Operators per Police Drone Vehicle', 'LIVE: fills Police Drone Vehicles to 2/2. Search Advisor dual-trained personnel are preserved where possible.', [POLICE_RULES.drone]),
                livePoliceProfile('police_eod_commander', 'EOD Commander', 'EOD Commander Vehicle', '2 EOD Commanders per vehicle', 'LIVE: fills EOD Commander vehicles to 2/2 before general Bomb Disposal vehicles in the full Police run.', [POLICE_RULES.eodCommander], ['EOD']),
                livePoliceProfile('police_firearms', 'Firearms training', 'Multi-Role Armoured Vehicle', '6 Firearms-trained officers per MRAV', 'LIVE: fills every MRAV to 6/6 with Firearms-trained personnel and preserves Roads Policing dual-trained officers where possible.', [POLICE_RULES.firearms]),
                livePoliceProfile(
                    'police_public_order_1',
                    'Level 1 Public Order Training',
                    'Normal Police IRV',
                    '2 Level 1 Public Order officers per IRV',
                    'LIVE INDIVIDUAL PROFILE: checks and assigns Level 1 Public Order training only. Other Police qualifications do not affect this result.',
                    [
                        POLICE_RULES
                            .publicOrderLevel1
                    ]
                ),
                livePoliceProfile(
                    'police_public_order_2',
                    'Level 2 Public Order Training',
                    'Normal Police IRV',
                    '2 Level 2 Public Order officers per IRV',
                    'LIVE INDIVIDUAL PROFILE: checks and assigns Level 2 Public Order training only. Other Police qualifications do not affect this result.',
                    [
                        POLICE_RULES
                            .publicOrderLevel2
                    ]
                ),
                livePoliceProfile('police_marine_bomb_disposal', 'Marine Bomb Disposal', 'Marine EOD Response and Equipment vehicles', 'Response 4/4; Equipment Van 3/3', 'LIVE: fills Marine EOD Response vehicles to 4/4 and Equipment Vans to 3/3 with Marine Bomb Disposal personnel.', [POLICE_RULES.marineResponse, POLICE_RULES.marineEquipment], ['EOD']),
                livePoliceProfile('police_mobile_operations_management', 'Mobile Operations Management', 'EIU', '2 Mobile Operations Managers per EIU', 'LIVE: fills each EIU to 2/2 with railway_police_command-trained personnel.', [POLICE_RULES.mobileOperations]),
                livePoliceProfile('police_mounted', 'Mounted Training', 'Mounted Unit', 'At least 1 Mounted Officer per vehicle', 'LIVE: meets the verified native minimum of one Mounted Officer per Mounted Unit. It does not fill the remaining passenger seats.', [POLICE_RULES.mounted]),
                livePoliceProfile('police_inspector', 'Police Inspector Training', 'Normal Police IRV', '2 Police Inspectors per allocated IRV', 'LIVE: uses normal IRVs and fills allocated vehicles to 2/2 with police_inspector-trained officers.', [POLICE_RULES.inspector]),
                livePoliceProfile(
                    'police_medic',
                    'Police Medic Training',
                    'Normal Police IRV',
                    '2 Police Medics per IRV',
                    'LIVE INDIVIDUAL PROFILE: checks and assigns Police Medic training only. Run all Police profiles retains the combined four-course crew rule.',
                    [
                        POLICE_RULES
                            .publicOrderMedic
                    ]
                ),
                livePoliceProfile('police_search_advisor', 'Police Search Advisor Training', 'Police Drone Vehicle', '2 dual-trained Drone/Search Advisor personnel', 'LIVE: both personnel must hold drone and search_and_rescue training.', [POLICE_RULES.searchAdvisor]),
                livePoliceProfile(
                    'police_sergeant',
                    'Police Sergeant Training',
                    'Normal Police IRV',
                    '2 Police Sergeants per IRV',
                    'LIVE INDIVIDUAL PROFILE: checks and assigns Police Sergeant training only. Run all Police profiles retains the combined four-course crew rule.',
                    [
                        POLICE_RULES
                            .publicOrderSergeant
                    ]
                ),
                livePoliceProfile('police_aviation', 'Police aviation', 'Police Helicopter', '3 Police Aviation personnel per helicopter', 'LIVE: fills each Police Helicopter to 3/3 with polizeihubschrauber-trained personnel.', [POLICE_RULES.aviation], ['AIR']),
                livePoliceProfile('police_railway', 'Railway Policing', 'Railway Policing IRV', '2 Railway Police Officers per IRV', 'LIVE: fills Railway Unit IRVs to 2/2 with railway_police-trained personnel and preserves Mobile Operations Managers where possible.', [POLICE_RULES.railway]),
                livePoliceProfile('police_roads', 'Roads Policing Officer Training', 'Armed Traffic Car', '2 dual-trained Roads Policing + Firearms officers', 'LIVE: both officers must hold traffic_police and swat.', [POLICE_RULES.roads]),
                {
                    id: 'all_police',
                    label: 'Run all Police profiles',
                    vehicle: 'All verified Police, Aviation and EOD vehicle groups',
                    requirement: 'Process verified profiles in safe reservation order',
                    policy: 'LIVE BATCH: preserves current assignments, assigns specialist and dual-trained roles first, allocates shared IRV/Drone pools safely, then verifies the station-wide result.',
                    live: true,
                    engine: 'police',
                    stationTypes: ['POLICE', 'AIR', 'EOD'],
                    rules: POLICE_ALL_RULES,
                    batch: true
                }
            ]
        },
        coastguard: {
            label: 'SAR / Mountain Rescue / Coastguard',
            icon: '🌊⛰️',
            profiles: [
                makeServicePreviewProfile('sar_cave_rescue', 'Cave Rescue Training', 'SAR'),
                makeServicePreviewProfile('sar_coastal_air_rescue', 'Coastal Air Rescue Operations Training', 'SAR'),
                makeServicePreviewProfile('sar_coastal_command', 'Coastal Command Training', 'SAR'),
                makeServicePreviewProfile('sar_search_advisor', 'Coastguard Search Advisor Training', 'SAR'),
                makeServicePreviewProfile('sar_dog_handling', 'Dog handling', 'SAR'),
                makeServicePreviewProfile('sar_drone_operator', 'Drone Operator Training', 'SAR'),
                makeServicePreviewProfile('sar_flood_first_responder', 'Flood First Responder Training', 'SAR'),
                makeServicePreviewProfile('sar_hovercraft_commander', 'Hovercraft Commander Training', 'SAR'),
                makeServicePreviewProfile('sar_jet_ski', 'Jet Ski Handling', 'SAR'),
                makeServicePreviewProfile('sar_lifeboat_operations', 'Lifeboat Operations Training', 'SAR'),
                makeServicePreviewProfile('sar_lifeguard', 'Lifeguard Training', 'SAR'),
                makeServicePreviewProfile('sar_mud_rescue', 'Mud Rescue Training', 'SAR'),
                makeServicePreviewProfile('sar_rope_rescue', 'Rope Rescue Training', 'SAR'),
                makeServicePreviewProfile('sar_search_management', 'Search Management Training', 'SAR'),
                {
                    id: 'all_sar',
                    label: 'Run all SAR / Mountain Rescue profiles',
                    vehicle: 'All mapped SAR, Mountain Rescue, Coastguard and Water Rescue vehicle groups',
                    requirement: 'Process enabled SAR and Mountain Rescue profiles in priority order',
                    policy: 'Future batch option. It remains disabled until every SAR profile has confirmed mappings.',
                    live: false,
                    stationTypes: ['SAR', 'COASTGUARD', 'RNLI']
                }
            ]
        },
        all_services: {
            label: 'All Services',
            icon: '🧭',
            profiles: [{
                id: 'all_services_profiles',
                label: 'Run all service profiles — future option',
                vehicle: 'All supported service vehicles',
                requirement: 'Process services and profiles in safe priority order',
                policy: 'This future option will only be enabled after each individual service is fully tested and live.',
                live: false,
                stationTypes: []
            }]
        }
    };

    const TYPE_ID_TO_VEHICLE_TYPE = {
        "3": "Fire Officer",
        "4": "Rescue Support Unit (RSU)",
        "5": "Ambulance",
        "6": "Water Carrier",
        "7": "HazMat Unit",
        "8": "Police Car",
        "9": "Air Ambulance",
        "10": "RRV",
        "11": "Police Helicopter",
        "12": "DSU",
        "15": "Incident Command and Control Unit",
        "16": "Rescue Pump",
        "17": "Combined Aerial Rescue Pump",
        "20": "OTL",
        "25": "Armed Traffic Car",
        "26": "Heavy 4x4 Tanker",
        "27": "PRV",
        "28": "SRV",
        "29": "Welfare Vehicle",
        "30": "ATV",
        "31": "Ambulance Control Unit",
        "33": "Mass Casualty Equipment",
        "34": "Ambulance Officer",
        "35": "BFU",
        "36": "F/WrC",
        "38": "RPF",
        "39": "Operational Support Unit",
        "51": "PSU Carrier",
        "54": "Detention Van",
        "55": "Mounted Unit",
        "56": "MRAV",
        "57": "Coastguard Rescue Vehicle",
        "58": "Mud Rescue Unit",
        "59": "Coastguard Rope Rescue Unit",
        "60": "Coastguard Commander",
        "61": "Flood Rescue Unit Trailer",
        "62": "Flood Rescue Unit",
        "63": "Support Unit",
        "65": "Coastguard Rescue Helicopter Large",
        "66": "4x4 Vehicle",
        "67": "ILB Trainer",
        "68": "ILB",
        "69": "ALB",
        "70": "Rescue Watercraft Trailer",
        "71": "Hovercraft Trailer",
        "72": "Hovercraft Transporter",
        "73": "Light 4x4",
        "74": "Boat Trailer",
        "75": "Major Foam Tender",
        "76": "RIV",
        "77": "Airfield Command",
        "78": "Rescue Stairs",
        "79": "Airfield Operations Vehicle",
        "80": "Airfield Operations Supervisor",
        "81": "Medical Equipment Trailer",
        "85": "Control Van SAR",
        "86": "Operational Support Van",
        "87": "Operational Support Trailer",
        "88": "SAR Flood Rescue Trailer",
        "89": "Drone Vehicle SAR HQ",
        "91": "Police Drone Vehicle",
        "93": "SAR 4x4",
        "96": "Specialist Paramedic RRV",
        "97": "Patient Transport Service Ambulance",
        "98": "Critical Care Transfer Ambulance",
        "99": "Mountain Rescue 4x4",
        "102": "Search Dog Unit SAR",
        "105": "Flatbed Recovery Vehicle",
        "107": "RRU",
        "108": "EIU",
        "109": "EOD Commander",
        "110": "EOD Response Vehicle",
        "111": "EOD Medium Equipment Van",
        "112": "EOD Heavy Equipment Vehicle",
        "113": "Marine EOD Response Vehicle",
        "114": "Marine EOD Equipment Van",
        "115": "Welfare Vehicle",
        "116": "Cell Van"
    };

    const VEHICLE_INFO = {
        "Ambulance": { code: "AB", icon: "🚑" },
        "Ambulance Officer": { code: "AO", icon: "🚑🎖️" },
        "Ambulance Control Unit": { code: "ACU", icon: "🚑📡" },
        "Air Ambulance": { code: "AA", icon: "🚁" },
        "Rescue Pump": { code: "RP", icon: "🚒" },
        "Combined Aerial Rescue Pump": { code: "CARP", icon: "🚒🪜" },
        "Fire Officer": { code: "FO", icon: "🧑‍🚒" },
        "Police Car": { code: "PC", icon: "🚔" },
        "Armed Traffic Car": { code: "ATC", icon: "🚔🔫" },
        "Operational Support Unit": { code: "OSU", icon: "☢️🤿🦺" },
        "Mass Casualty Equipment": { code: "MCE", icon: "🏥" },
        "Welfare Vehicle": { code: "WV", icon: "🚌" },
        "HazMat Unit": { code: "HMAT", icon: "☢️" },
        "Water Carrier": { code: "WrC", icon: "🚒💦" },
        "Incident Command and Control Unit": { code: "ICCU", icon: "🔥🚒🔥" },
        "Heavy 4x4 Tanker": { code: "H4x4T", icon: "🚒💦" },
        "Police Helicopter": { code: "POLHELI", icon: "🚔🚁" },
        "Police Drone Vehicle": { code: "PDV", icon: "🚔🚁" },
        "EIU": { code: "EIU", icon: "🚔📡" },
        "PSU Carrier": { code: "PSU", icon: "🚔🚌" },
        "Detention Van": { code: "DV", icon: "🚔🥅" },
        "Mounted Unit": { code: "MU", icon: "🚔🐎" },
        "Coastguard Rescue Vehicle": { code: "CRV", icon: "⚠️🛻" },
        "Mud Rescue Unit": { code: "MRU", icon: "⚠️🟤" },
        "Coastguard Rope Rescue Unit": { code: "CRRU", icon: "⚠️🧗" },
        "Coastguard Commander": { code: "CGC", icon: "⚠️👨‍✈️" },
        "Coastguard Rescue Helicopter Large": { code: "CGH", icon: "🚁⚠️" },
        "Flood Rescue Unit Trailer": { code: "FRUT", icon: "🛟" },
        "Flood Rescue Unit": { code: "FRU", icon: "🛟" },
        "Support Unit": { code: "SU", icon: "⚠️🚐" },
        "4x4 Vehicle": { code: "4x4", icon: "🛟" },
        "ILB Trainer": { code: "ILBT", icon: "🚤" },
        "ILB": { code: "ILB", icon: "🚤" },
        "ALB": { code: "ALB", icon: "🚤" },
        "Boat Trailer": { code: "BT", icon: "🚤" },
        "Rescue Watercraft Trailer": { code: "RWC", icon: "🚤" },
        "Hovercraft Trailer": { code: "HCT", icon: "🛥️" },
        "Hovercraft Transporter": { code: "HCTR", icon: "🛥️" },
        "Light 4x4": { code: "L4x4", icon: "🚙" },
        "Major Foam Tender": { code: "MFT", icon: "🚒✈️" },
        "RIV": { code: "RIV", icon: "🚒✈️" },
        "Airfield Command": { code: "AirCommand", icon: "🚒✈️" },
        "Rescue Stairs": { code: "RS", icon: "✈️🪜" },
        "Airfield Operations Vehicle": { code: "AOV", icon: "✈️🚗" },
        "Airfield Operations Supervisor": { code: "AOS", icon: "✈️👷" },
        "Medical Equipment Trailer": { code: "MET", icon: "🚒⚕️" },
        "Control Van SAR": { code: "CV", icon: "📡" },
        "Operational Support Van": { code: "OSV", icon: "🛠️" },
        "Operational Support Trailer": { code: "OST", icon: "🛠️" },
        "SAR Flood Rescue Trailer": { code: "SFR", icon: "🌊" },
        "Drone Vehicle SAR HQ": { code: "DRV", icon: "🚁" },
        "SAR 4x4": { code: "SAR4x4", icon: "🟡" },
        "Specialist Paramedic RRV": { code: "SP-RRV", icon: "🚑" },
        "Patient Transport Service Ambulance": { code: "PTS", icon: "🚑" },
        "Critical Care Transfer Ambulance": { code: "CCT", icon: "🚑❤️" },
        "Mountain Rescue 4x4": { code: "MR4x4", icon: "🏔️" },
        "Search Dog Unit SAR": { code: "K9", icon: "🐕" },
        "Flatbed Recovery Vehicle": { code: "FRV", icon: "🛻" },
        "RRV": { code: "RRV", icon: "🚑" },
        "RRU": { code: "RRU", icon: "🚒✈️" },
        "Rescue Support Unit (RSU)": { code: "RSU", icon: "🚒🛠️" },
        "DSU": { code: "DSU", icon: "🚔🐕" },
        "OTL": { code: "OTL", icon: "🚔" },
        "PRV": { code: "PRV", icon: "🚑1️⃣" },
        "SRV": { code: "SRV", icon: "🚑2️⃣" },
        "ATV": { code: "ATV", icon: "🚑🦺" },
        "BFU": { code: "BFU", icon: "🚒✈️" },
        "F/WrC": { code: "FWrC", icon: "🚒💦" },
        "RPF": { code: "RPF", icon: "🚒🫧" },
        "MRAV": { code: "MRAV", icon: "🚔🔫" },
        "EOD Commander": { code: "EODC", icon: "💣" },
        "EOD Response Vehicle": { code: "EOD", icon: "💣🚐" },
        "EOD Medium Equipment Van": { code: "EODM", icon: "💣🚐" },
        "EOD Heavy Equipment Vehicle": { code: "EODH", icon: "💣🚚" },
        "Marine EOD Response Vehicle": { code: "MEOD", icon: "💣🚤" },
        "Marine EOD Equipment Van": { code: "MEODV", icon: "💣🚐" },
        "Cell Van": { code: "CVAN", icon: "🚔🚐" }
    };

    const UNIT_CLASS_ALL = 'ALL';
    const UNIT_CLASS_TYPE_IDS_BY_STATION_TYPE = Object.freeze({
        AMBULANCE: Object.freeze([
            '5', '10', '27', '28', '30', '31', '33', '34', '96', '97', '98'
        ]),
        FIRE: Object.freeze([
            '3', '4', '6', '7', '15', '16', '17', '26', '29', '35', '36', '38', '39'
        ]),
        POLICE: Object.freeze([
            '8', '11', '12', '20', '25', '51', '54', '55', '56', '91', '108', '115', '116'
        ]),
        AIR: Object.freeze([
            '9', '11', '65'
        ]),
        AIRFIELD: Object.freeze([
            '73', '75', '76', '77', '78', '79', '80', '81', '107'
        ]),
        COASTGUARD: Object.freeze([
            '57', '58', '59', '60', '61', '62', '63', '65', '66', '70', '71', '72'
        ]),
        RNLI: Object.freeze([
            '67', '68', '69', '70', '74'
        ]),
        SAR: Object.freeze([
            '61', '62', '63', '66', '70', '71', '72', '85', '86', '87', '88', '89', '93', '99', '102'
        ]),
        EOD: Object.freeze([
            '109', '110', '111', '112', '113', '114'
        ]),
        RECOVERY: Object.freeze([
            '105'
        ])
    });

    const STATION_TYPES = {
        ALL: "All station types",
        AMBULANCE: "Ambulance",
        FIRE: "Fire",
        POLICE: "Police",
        AIR: "Air / Heli",
        COASTGUARD: "Coastguard",
        RNLI: "RNLI / Lifeboat",
        SAR: "SAR",
        AIRFIELD: "Airfield",
        EOD: "EOD / Bomb",
        RECOVERY: "Recovery",
        OTHER: "Other"
    };


    // MissionChief's own building type IDs. These are read from the parent
    // .building_list_li element and do not depend on uploaded station images.
    const STATION_BUILDING_TYPE_INFO = {
        0:  { stationType: 'FIRE',       suffix: '-FS',   label: 'Fire station' },
        18: { stationType: 'FIRE',       suffix: '-FS',   label: 'Small fire station' },
        2:  { stationType: 'AMBULANCE',  suffix: '-AS',   label: 'Ambulance station' },
        20: { stationType: 'AMBULANCE',  suffix: '-AS',   label: 'Small ambulance station' },
        6:  { stationType: 'POLICE',     suffix: '-PS',   label: 'Police station' },
        19: { stationType: 'POLICE',     suffix: '-PS',   label: 'Small police station' },
        5:  { stationType: 'AIR',        suffix: '-AA',   label: 'Air ambulance station' },
        13: { stationType: 'AIR',        suffix: '-PH',   label: 'Police helicopter station' },
        27: { stationType: 'RNLI',       suffix: '-RNLI', label: 'RNLI / lifeboat station' },
        28: { stationType: 'COASTGUARD', suffix: '-CG',   label: 'Coastguard station' },
        30: { stationType: 'COASTGUARD', suffix: '-CG',   label: 'Coastguard helicopter station' },
        33: { stationType: 'SAR',        suffix: '-SAR',  label: 'Search and rescue station' },
        34: { stationType: 'RECOVERY',   suffix: '-REC',  label: 'Recovery station' },
        35: { stationType: 'EOD',        suffix: '-EOD',  label: 'EOD / bomb disposal station' }
    };

    const STATE = {
        running: false,
        paused: false,
        stopped: false,
        debug: false,
        stations: [],
        filteredStations: [],
        stationIndex: 0,
        renamedCount: 0,
        skippedCount: 0,
        mode: "all",
        selectedUnitClass: UNIT_CLASS_ALL,
        runId: 0,
        activeIframe: null
    };

    const STATION_STATE = {
        running: false,
        paused: false,
        stopped: false,
        debug: false,
        stations: [],
        filteredStations: [],
        queue: [],
        selectedHref: '',
        mode: 'all',
        action: 'preview',
        stationIndex: 0,
        renamedCount: 0,
        skippedCount: 0,
        previewedCount: 0,
        activeIframe: null,
        buildingCoordinateCache: new Map(),
        buildingDataPromise: null,
        activeControllers: new Set()
    };

    const PERSONNEL_STATE = {
        running: false,
        paused: false,
        stopped: false,
        debug: false,
        stations: [],
        filteredStations: [],
        queue: [],
        selectedHref: '',
        service: 'medical',
        profile: 'critical_care',
        mode: 'all',
        action: 'preview',
        registerBuilding: false,
        configuredUnitsRequired: 0,
        unitsRequired: 0,
        unitsFulfilled: 0,
        unitTargetReached: false,
        stationsTargetMet: 0,
        stationsTargetShort: 0,
        stationIndex: 0,
        completedStations: 0,
        skippedStations: 0,
        checkedVehicles: 0,
        plannedCount: 0,
        assignedCount: 0,
        trainingShortfall: 0,
        assignmentShortfall: 0,
        reports: [],
        currentReport: '',
        currentStationReport: '',
        lastStationReport: null,
        activeController: null,
        lastRequestAt: 0
    };

    const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

    function registerToolLifecycleCleanup(cleanup) {
        if (typeof cleanup === 'function') {
            TOOL_LIFECYCLE_CLEANUPS.add(cleanup);
        }
        return cleanup;
    }

    function runToolLifecycleCleanup() {
        if (TOOL_LIFECYCLE_CLEANED) return;
        TOOL_LIFECYCLE_CLEANED = true;

        STATE.stopped = true;
        STATE.paused = false;

        const activeUnitIframe = STATE.activeIframe;
        STATE.activeIframe = null;
        releaseUnitIframeDocument(activeUnitIframe);
        STATE.stations = [];
        STATE.filteredStations = [];
        STATION_STATE.stopped = true;
        STATION_STATE.paused = false;
        PERSONNEL_STATE.stopped = true;
        PERSONNEL_STATE.paused = false;

        flushPersonnelTrainingRegistry(true);

        if (PERSONNEL_STATE.activeController) {
            try {
                PERSONNEL_STATE.activeController.abort();
            } catch (_error) {}
            PERSONNEL_STATE.activeController = null;
        }

        for (const controller of STATION_STATE.activeControllers) {
            try {
                controller.abort();
            } catch (_error) {}
        }
        STATION_STATE.activeControllers.clear();

        for (const cleanup of [...TOOL_LIFECYCLE_CLEANUPS]) {
            try {
                cleanup();
            } catch (_error) {}
        }
        TOOL_LIFECYCLE_CLEANUPS.clear();

        for (const frameId of TOOL_LOG_SCROLL_FRAMES.values()) {
            try {
                cancelAnimationFrame(frameId);
            } catch (_error) {}
        }
        TOOL_LOG_SCROLL_FRAMES.clear();
        TOOL_UI_ELEMENT_CACHE.clear();
        PERSONNEL_STATION_LINK_BY_HREF.clear();
        PERSONNEL_START_OPTION_BY_HREF.clear();
        PERSONNEL_HIGHLIGHTED_STATION_LINKS.clear();

        STATION_STATE.activeIframe = null;
        STATION_STATE.buildingCoordinateCache.clear();
        STATION_STATE.buildingDataPromise = null;
        PERSONNEL_STATE.reports = [];
        PERSONNEL_STATE.lastStationReport = null;
        PERSONNEL_STATE.currentReport = '';
        PERSONNEL_STATE.currentStationReport = '';
        PERSONNEL_TRAINING_REGISTRY_CACHE = null;
        PERSONNEL_SHORTFALL_CACHE = [];
        PERSONNEL_SHORTFALL_CACHE_SIZE = -1;
    }

    function getToolElementById(id) {
        const key = String(id || '');
        if (!key) return null;

        const cached = TOOL_UI_ELEMENT_CACHE.get(key);
        if (cached?.isConnected) return cached;

        const element = document.getElementById(key);
        if (element) TOOL_UI_ELEMENT_CACHE.set(key, element);
        else TOOL_UI_ELEMENT_CACHE.delete(key);
        return element;
    }

    function clearBoundedToolLog(logBox) {
        if (!logBox) return;

        const frameId = TOOL_LOG_SCROLL_FRAMES.get(logBox);
        if (frameId != null) {
            try {
                cancelAnimationFrame(frameId);
            } catch (_error) {}
            TOOL_LOG_SCROLL_FRAMES.delete(logBox);
        }

        logBox.replaceChildren();
    }

    function appendBoundedToolLog(logBox, line) {
        if (!logBox || !line) return;

        logBox.appendChild(line);

        if (logBox.childElementCount > TOOL_LOG_MAX_LINES + TOOL_LOG_TRIM_BUFFER) {
            const removeCount = logBox.childElementCount - TOOL_LOG_MAX_LINES;
            for (let index = 0; index < removeCount; index++) {
                logBox.firstElementChild?.remove();
            }
        }

        if (!TOOL_LOG_SCROLL_FRAMES.has(logBox)) {
            const frameId = requestAnimationFrame(() => {
                TOOL_LOG_SCROLL_FRAMES.delete(logBox);
                if (logBox.isConnected) logBox.scrollTop = logBox.scrollHeight;
            });
            TOOL_LOG_SCROLL_FRAMES.set(logBox, frameId);
        }
    }

    function isIosSafariWebsite() {
        const userAgent = String(navigator.userAgent || '');
        const platform = String(navigator.platform || '');
        const isIosDevice = /iP(?:ad|hone|od)/i.test(userAgent)
            || (
                platform === 'MacIntel'
                && Number(navigator.maxTouchPoints || 0) > 1
            );
        const isSafariBrowser = /Safari/i.test(userAgent)
            && !/(?:CriOS|FxiOS|EdgiOS|OPiOS|DuckDuckGo)/i.test(userAgent);

        // Native WKWebView/app wrappers normally omit the Safari token. This
        // deliberately targets the MissionChief website opened in Safari.
        return isIosDevice
            && isSafariBrowser
            && /^https?:$/i.test(String(location.protocol || ''));
    }

    const STATION_OVERVIEW_LINK_SELECTOR = [
        'a.lightbox-open.list-group-item.active[href*="/buildings/"]',
        'a.lightbox-open[href*="/buildings/"]',
        '.building_list_li a[href*="/buildings/"]',
        '.building_list a[href*="/buildings/"]',
        '[data-building-id] a[href*="/buildings/"]'
    ].join(',');

    function normaliseStationOverviewHref(value) {
        try {
            const url = new URL(String(value || ''), location.origin);
            if (url.origin !== location.origin) return '';
            const match = url.pathname.match(/^\/buildings\/(\d+)\/?$/);
            return match ? `/buildings/${match[1]}` : '';
        } catch (_error) {
            return '';
        }
    }

    function isGenericStationActionText(value) {
        return /^(?:details?|open|show|view|edit|move|vehicles?|personnel|education|extensions?)$/i
            .test(cleanText(value));
    }

    function getStationOverviewContainer(link) {
        return link?.closest?.(
            '.building_list_li, .building_list, [building_type_id], ' +
            '[data-building-type-id], [data-building-id], [id^="building_"]'
        ) || link?.closest?.('li, .panel, .card, .well') || link?.parentElement || null;
    }

    function readStationBuildingTypeId(link, container = getStationOverviewContainer(link)) {
        const candidates = [
            link?.closest?.('[building_type_id], [data-building-type-id]'),
            container,
            container?.querySelector?.('[building_type_id], [data-building-type-id]')
        ].filter(Boolean);

        for (const candidate of candidates) {
            const raw =
                candidate.getAttribute?.('building_type_id') ??
                candidate.getAttribute?.('data-building-type-id') ??
                candidate.dataset?.buildingTypeId ??
                '';
            if (raw !== '' && Number.isFinite(Number(raw))) return Number(raw);
        }

        return null;
    }

    function scoreStationOverviewLink(link, href) {
        let score = 0;
        if (link.classList?.contains('lightbox-open')) score += 100;
        if (link.matches?.('.list-group-item.active')) score += 70;
        if (normaliseStationOverviewHref(link.getAttribute?.('href')) === href) score += 40;
        const label = cleanText(link.textContent || link.getAttribute?.('aria-label') || '');
        if (label && !isGenericStationActionText(label)) score += 35;
        if (link.offsetParent !== null) score += 10;
        return score;
    }

    function readStationOverviewName(link, container, href) {
        const values = [];
        const add = value => {
            const cleaned = cleanText(value);
            if (!cleaned || isGenericStationActionText(cleaned)) return;
            if (!values.includes(cleaned)) values.push(cleaned);
        };

        add(container?.getAttribute?.('search_attribute'));
        add(container?.getAttribute?.('data-building-name'));
        add(container?.dataset?.buildingName);

        const sameBuildingLinks = container
            ? [...container.querySelectorAll('a[href]')]
                .filter(candidate => normaliseStationOverviewHref(candidate.getAttribute('href')) === href)
                .sort((a, b) => scoreStationOverviewLink(b, href) - scoreStationOverviewLink(a, href))
            : [link];

        sameBuildingLinks.forEach(candidate => {
            add(candidate.getAttribute?.('aria-label'));
            add(candidate.getAttribute?.('title'));
            add(candidate.textContent);
        });

        const nameSelectors = [
            '[data-building-name]',
            '.building_list_title',
            '.building-list-title',
            '.building_name',
            '.building-name',
            '.panel-heading',
            '.card-title',
            'h1', 'h2', 'h3', 'h4'
        ];

        for (const selector of nameSelectors) {
            container?.querySelectorAll?.(selector).forEach(node => {
                add(node.getAttribute?.('data-building-name'));
                add(node.textContent);
            });
        }

        if (!values.length && container) {
            const clone = container.cloneNode(true);
            clone.querySelectorAll(
                'button, .btn, table, tbody, .vehicle, .vehicle_list, ' +
                '[vehicle_id], [data-vehicle-id], a[href*="/vehicles/"]'
            ).forEach(node => node.remove());
            String(clone.textContent || '')
                .split(/[\r\n]+/)
                .map(value => cleanText(value))
                .filter(Boolean)
                .forEach(add);
        }

        return values[0] || `Building ${getBuildingIdFromHref(href) || ''}`.trim();
    }

    function getStationOverviewEntries(root = document) {
        const groups = new Map();

        root.querySelectorAll(STATION_OVERVIEW_LINK_SELECTOR).forEach(link => {
            if (link.closest?.('#mc-namer-panel')) return;
            const href = normaliseStationOverviewHref(link.getAttribute?.('href'));
            if (!href) return;

            const container = getStationOverviewContainer(link);
            if (!container && !link.matches?.('.lightbox-open.list-group-item.active')) return;

            const candidates = groups.get(href) || [];
            candidates.push({ link, container });
            groups.set(href, candidates);
        });

        return [...groups.entries()].map(([href, candidates], index) => {
            candidates.sort((a, b) =>
                scoreStationOverviewLink(b.link, href) -
                scoreStationOverviewLink(a.link, href)
            );
            const selected = candidates[0];
            const container = selected.container || getStationOverviewContainer(selected.link);
            return {
                index,
                href,
                buildingId: getBuildingIdFromHref(href),
                displayName: readStationOverviewName(selected.link, container, href),
                buildingTypeId: readStationBuildingTypeId(selected.link, container),
                link: selected.link,
                container
            };
        });
    }

    function findStationOverviewEntry(href) {
        const expected = normaliseStationOverviewHref(href);
        if (!expected) return null;
        return getStationOverviewEntries().find(entry => entry.href === expected) || null;
    }

    function activateStationOverviewEntry(entry) {
        const link = entry?.link;
        if (!link?.isConnected) return false;

        if (!isIosSafariWebsite() || link.classList.contains('lightbox-open')) {
            link.click();
            return true;
        }

        // Responsive iOS markup may expose a normal Details link without the
        // desktop lightbox class. Temporarily opt that exact building link into
        // MissionChief's delegated lightbox handler while preventing navigation.
        link.classList.add('lightbox-open');
        const preventNavigation = event => event.preventDefault();
        link.addEventListener('click', preventNavigation, { capture: true, once: true });
        link.click();
        setTimeout(() => link.classList.remove('lightbox-open'), 0);
        return true;
    }

    function createManagedStationIframe(stationHref, purpose = 'station') {
        const href = normaliseStationOverviewHref(stationHref);
        if (!href) return null;

        document.querySelectorAll(
            `iframe.mc-namer-managed-station-iframe[data-mc-purpose="${purpose}"]`
        ).forEach(frame => frame.remove());

        const iframe = document.createElement('iframe');
        iframe.className = 'mc-namer-managed-station-iframe';
        iframe.dataset.mcPurpose = purpose;
        iframe.src = href;
        iframe.setAttribute('aria-hidden', 'true');
        iframe.tabIndex = -1;
        Object.assign(iframe.style, {
            position: 'fixed',
            left: '-10000px',
            top: '0',
            width: '2px',
            height: '2px',
            opacity: '0.01',
            pointerEvents: 'none',
            border: '0'
        });
        document.body.appendChild(iframe);
        return iframe;
    }

    function removeManagedStationIframe(iframe) {
        if (!iframe?.classList?.contains('mc-namer-managed-station-iframe')) {
            return false;
        }
        try {
            iframe.src = 'about:blank';
        } catch (_error) {}
        iframe.remove();
        return true;
    }

    async function openStationWorkflowIframe(entry, purpose, waitForIframe) {
        if (!entry?.link?.isConnected) return null;

        if (isIosSafariWebsite() && !entry.link.classList.contains('lightbox-open')) {
            const managed = createManagedStationIframe(entry.href, purpose);
            return managed ? await waitForIframe(entry.href, managed) : null;
        }

        activateStationOverviewEntry(entry);
        const normal = await waitForIframe(entry.href, null, 24);
        if (normal || !isIosSafariWebsite()) return normal;

        // Safari can render a responsive Details link while MissionChief's
        // lightbox binding is unavailable. Fall back to a same-origin managed
        // iframe so naming and personnel-safe station reads still work without
        // navigating away from the Stations tab.
        const managed = createManagedStationIframe(entry.href, purpose);
        return managed ? await waitForIframe(entry.href, managed) : null;
    }

    function ensureSingleNamingToolsPanel(preferredPanel = null) {
        const panels = [...document.querySelectorAll('#mc-namer-panel')];
        const keeper = preferredPanel?.isConnected
            ? preferredPanel
            : panels[0] || null;

        panels.forEach(panel => {
            if (panel !== keeper) panel.remove();
        });

        const styles = [...document.querySelectorAll('style[data-mc-namer-style="true"]')];
        styles.forEach((style, index) => {
            if (index > 0) style.remove();
        });

        return keeper;
    }

    function installSingleNamingToolsPanelGuard(panel) {
        let pending = false;
        const enforce = () => {
            if (pending) return;
            pending = true;
            requestAnimationFrame(() => {
                pending = false;
                ensureSingleNamingToolsPanel(panel?.isConnected ? panel : null);
            });
        };

        const observer = new MutationObserver(records => {
            const panelMutation = records.some(record =>
                [...record.addedNodes].some(node =>
                    node?.nodeType === Node.ELEMENT_NODE && (
                        node.matches?.('#mc-namer-panel') ||
                        node.querySelector?.('#mc-namer-panel')
                    )
                )
            );
            if (panelMutation) enforce();
        });
        observer.observe(document.documentElement, { childList: true, subtree: true });
        window.addEventListener('pageshow', enforce, { passive: true });

        registerToolLifecycleCleanup(() => {
            observer.disconnect();
            window.removeEventListener('pageshow', enforce);
        });

        enforce();
    }

    function getToolViewportBounds() {
        const viewport = window.visualViewport;
        const left = Math.max(0, Number(viewport?.offsetLeft || 0));
        const top = Math.max(0, Number(viewport?.offsetTop || 0));
        const width = Math.max(1, Number(viewport?.width || window.innerWidth || 1));
        const height = Math.max(1, Number(viewport?.height || window.innerHeight || 1));

        return {
            left,
            top,
            width,
            height,
            right: left + width,
            bottom: top + height
        };
    }

    function clampToolPanelToViewport(panel) {
        if (!panel?.isConnected) return;

        // Before the first drag, iOS Safari is positioned entirely by the
        // safe-area CSS below. Only clamp an explicitly dragged mobile panel.
        if (
            panel.classList.contains('mc-ios-safari')
            && !panel.style.left
        ) {
            return;
        }

        const bounds = getToolViewportBounds();
        let rect = panel.getBoundingClientRect();
        const maximumWidth = Math.max(260, bounds.width - 16);

        if (rect.width > maximumWidth) {
            panel.style.width = `${maximumWidth}px`;
            rect = panel.getBoundingClientRect();
        }

        const maximumLeft = Math.max(
            bounds.left,
            bounds.right - rect.width
        );
        const maximumTop = Math.max(
            bounds.top,
            bounds.bottom - rect.height
        );
        const nextLeft = Math.min(
            maximumLeft,
            Math.max(bounds.left, rect.left)
        );
        const nextTop = Math.min(
            maximumTop,
            Math.max(bounds.top, rect.top)
        );

        panel.style.left = `${nextLeft}px`;
        panel.style.top = `${nextTop}px`;
        panel.style.right = 'auto';
    }

    function installToolViewportGuard(panel) {
        let pendingFrame = null;

        const requestClamp = () => {
            if (pendingFrame != null) return;
            pendingFrame = requestAnimationFrame(() => {
                pendingFrame = null;
                clampToolPanelToViewport(panel);
            });
        };

        const resetIosPosition = () => {
            if (panel.classList.contains('mc-ios-safari')) {
                panel.style.left = '';
                panel.style.top = '';
                panel.style.right = '';
                panel.style.width = '';
            }
            requestClamp();
        };

        window.addEventListener('resize', requestClamp, { passive: true });
        window.addEventListener('orientationchange', resetIosPosition, { passive: true });
        window.addEventListener('pageshow', requestClamp, { passive: true });
        window.visualViewport?.addEventListener('resize', requestClamp, { passive: true });
        window.visualViewport?.addEventListener('scroll', requestClamp, { passive: true });

        registerToolLifecycleCleanup(() => {
            if (pendingFrame != null) {
                cancelAnimationFrame(pendingFrame);
                pendingFrame = null;
            }
            window.removeEventListener('resize', requestClamp);
            window.removeEventListener('orientationchange', resetIosPosition);
            window.removeEventListener('pageshow', requestClamp);
            window.visualViewport?.removeEventListener('resize', requestClamp);
            window.visualViewport?.removeEventListener('scroll', requestClamp);
        });

        requestClamp();
    }

    function initWhenReady() {
        let tries = 0;
        let timer = null;
        let observer = null;
        const maximumTries = isIosSafariWebsite()
            ? 120
            : 40;

        const removeReadinessListeners = () => {
            if (timer != null) {
                clearInterval(timer);
                timer = null;
            }
            observer?.disconnect();
            observer = null;
            window.removeEventListener('pageshow', tryInitialise);
            document.removeEventListener('visibilitychange', tryInitialise);
            TOOL_LIFECYCLE_CLEANUPS.delete(removeReadinessListeners);
        };

        function tryInitialise() {
            if (ensureSingleNamingToolsPanel()) {
                removeReadinessListeners();
                return true;
            }

            if (!isStationOverviewScreen()) return false;

            removeReadinessListeners();
            init();
            return true;
        }

        if (tryInitialise()) return;

        timer = setInterval(() => {
            tries++;
            if (tryInitialise()) return;
            if (tries >= maximumTries) {
                clearInterval(timer);
                timer = null;
            }
        }, 500);

        // Mobile Safari can restore the page from bfcache or populate the
        // responsive building list after the userscript has already started.
        if (isIosSafariWebsite()) {
            observer = new MutationObserver(() => {
                tryInitialise();
            });
            observer.observe(
                document.documentElement,
                {
                    childList: true,
                    subtree: true
                }
            );
            window.addEventListener('pageshow', tryInitialise, { passive: true });
            document.addEventListener('visibilitychange', tryInitialise, { passive: true });
        }

        registerToolLifecycleCleanup(removeReadinessListeners);
    }


    function isStationOverviewScreen() {
        const entries = getStationOverviewEntries();
        if (!entries.length) return false;

        const hasDesktopStationEntry = entries.some(entry =>
            entry.link?.matches?.(
                'a.lightbox-open.list-group-item.active[href*="/buildings/"]'
            )
        );
        if (hasDesktopStationEntry) return true;

        if (!isIosSafariWebsite()) return false;

        return entries.some(entry =>
            entry.container?.matches?.(
                '.building_list_li, .building_list, [data-building-id], [id^="building_"]'
            )
        );
    }


    function init() {
        addPanel();
        log(`Unit Naming Tool v${UNIT_VERSION} loaded. Press Refresh Stations first.`, 'info');
        stationLog(`Station Naming Tool v${STATION_VERSION} loaded. Refresh stations, choose Preview or Rename and Save, then press Start.`, 'info');
        personnelLog(`Personnel Assignment v${PERSONNEL_VERSION} loaded. Medical Critical Care and the verified Police profiles are live; other services remain in safe UI preview.`, 'info');
    }

    function addPanel() {
        if (ensureSingleNamingToolsPanel()) return;

        const panel = document.createElement('div');
        panel.id = 'mc-namer-panel';
        panel.classList.toggle('mc-ios-safari', isIosSafariWebsite());

        panel.innerHTML = `
            <div id="mc-namer-header">
                <span id="mc-namer-header-title">🚒 Unit Naming Tool v${UNIT_VERSION}</span>
                <button id="mc-namer-collapse" type="button" aria-expanded="true" title="Collapse naming tools">−</button>
            </div>

            <div id="mc-namer-body">
            <div class="mc-namer-tabs" role="tablist" aria-label="Naming tools">
                <button id="mc-tab-unit" class="mc-namer-tab active" type="button" role="tab" aria-selected="true">
                    🚒 Unit Naming Tool
                </button>
                <button id="mc-tab-station" class="mc-namer-tab" type="button" role="tab" aria-selected="false">
                    🏢 Station Naming Tool
                </button>
                <button id="mc-tab-personnel" class="mc-namer-tab" type="button" role="tab" aria-selected="false">
                    👥 Personnel Assignment
                </button>
            </div>

            <div id="mc-unit-view" class="mc-tool-view">
                <div class="mc-namer-section">
                    <label><b>Station Type:</b></label>
                    <select id="mc-namer-station-type">
                        ${Object.entries(STATION_TYPES).map(([key, label]) => `<option value="${key}">${label}</option>`).join('')}
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Unit Class:</b></label>
                    <select id="mc-namer-unit-class">
                        <option value="ALL">All classes</option>
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Mode:</b></label>
                    <select id="mc-namer-mode">
                        <option value="all">All matching stations from selected start point</option>
                        <option value="single">Selected station only</option>
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Start From:</b></label>
                    <select id="mc-namer-startfrom">
                        <option value="">Refresh stations first</option>
                    </select>
                </div>

                <div class="mc-namer-buttons">
                    <button id="mc-namer-refresh">Refresh Stations</button>
                    <button id="mc-namer-start">Start</button>
                    <button id="mc-namer-pause">Pause</button>
                    <button id="mc-namer-stop">Stop</button>
                    <button id="mc-namer-debug">Debug: OFF</button>
                    <button id="mc-namer-clear">Clear Log</button>
                </div>

                <div class="mc-namer-section">
                    <div><b>Status:</b> <span id="mc-namer-status">Idle</span></div>
                    <div><b>Station:</b> <span id="mc-namer-station">None</span></div>
                    <div><b>Vehicle:</b> <span id="mc-namer-vehicle">None</span></div>
                    <div><b>Progress:</b> <span id="mc-namer-progress">0 / 0</span></div>
                    <div><b>Renamed:</b> <span id="mc-namer-renamed">0</span></div>
                    <div><b>Skipped:</b> <span id="mc-namer-skipped">0</span></div>
                </div>

                <div id="mc-namer-log"></div>
            </div>

            <div id="mc-station-view" class="mc-tool-view" style="display:none;">
                <div class="mc-namer-section">
                    <label><b>Station Type:</b></label>
                    <select id="mc-station-type">
                        ${Object.entries(STATION_TYPES).map(([key, label]) => `<option value="${key}">${label}</option>`).join('')}
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Mode:</b></label>
                    <select id="mc-station-mode">
                        <option value="all">All matching stations from selected start point</option>
                        <option value="single">Selected station only</option>
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Action:</b></label>
                    <select id="mc-station-action">
                        <option value="preview">Preview only - do not save</option>
                        <option value="save">Rename and save</option>
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Start From:</b></label>
                    <select id="mc-station-startfrom">
                        <option value="">Refresh stations first</option>
                    </select>
                </div>

                <div class="mc-namer-buttons">
                    <button id="mc-station-refresh">Refresh Stations</button>
                    <button id="mc-station-start">Start</button>
                    <button id="mc-station-pause">Pause</button>
                    <button id="mc-station-stop">Stop</button>
                    <button id="mc-station-debug">Debug: OFF</button>
                    <button id="mc-station-clear">Clear Log</button>
                </div>

                <div class="mc-namer-section">
                    <div><b>Status:</b> <span id="mc-station-status">Idle</span></div>
                    <div><b>Station:</b> <span id="mc-station-current">None</span></div>
                    <div><b>Address:</b> <span id="mc-station-address">None</span></div>
                    <div><b>Town:</b> <span id="mc-station-town">None</span></div>
                    <div><b>Before:</b> <span id="mc-station-before">None</span></div>
                    <div><b>After:</b> <span id="mc-station-after">None</span></div>
                    <div><b>Progress:</b> <span id="mc-station-progress">0 / 0</span></div>
                    <div><b>Renamed:</b> <span id="mc-station-renamed">0</span></div>
                    <div><b>Skipped:</b> <span id="mc-station-skipped">0</span></div>
                </div>

                <div id="mc-station-log"></div>
            </div>

            <div id="mc-personnel-view" class="mc-tool-view" style="display:none;">
                <div class="mc-namer-section mc-personnel-navigation-section">
                    <div class="mc-personnel-navigation-title">Assignment Navigator</div>

                    <label style="display:block;"><b>Service:</b></label>
                    <select id="mc-personnel-service">
                        ${Object.entries(PERSONNEL_SERVICE_DEFINITIONS).map(([key, service]) => `<option value="${key}">${service.icon} ${service.label}</option>`).join('')}
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Training profile:</b></label>
                    <select id="mc-personnel-profile"></select>

                    <div id="mc-personnel-profile-banner" class="mc-personnel-profile-banner"></div>

                    <div class="mc-personnel-fixed-grid">
                        <div><b>Training:</b><br><span id="mc-personnel-profile-training">${PERSONNEL_TRAINING_LABEL}</span></div>
                        <div><b>Vehicle:</b><br><span id="mc-personnel-profile-vehicle">${PERSONNEL_TARGET_VEHICLE_LABEL}</span></div>
                        <div><b>Required:</b><br><span id="mc-personnel-profile-requirement">${PERSONNEL_TARGET_PER_VEHICLE} trained staff per vehicle</span></div>
                    </div>

                    <div id="mc-personnel-policy-summary" class="mc-personnel-policy-summary"></div>

                    <label style="margin-top:8px; display:block;"><b>Mode:</b></label>
                    <select id="mc-personnel-mode">
                        <option id="mc-personnel-mode-all-option" value="all">All relevant stations from selected start point — scan every station</option>
                        <option value="target">Ensure each relevant station has Units required</option>
                        <option value="single">Selected station only</option>
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Action:</b></label>
                    <select id="mc-personnel-action">
                        <option value="preview">Preview only - do not change assignments</option>
                        <option value="assign">Assign and verify</option>
                    </select>

                    <label style="margin-top:6px; display:block;"><b>Units required:</b></label>
                    <input id="mc-personnel-units-required" type="number" min="0" step="1" value="0" inputmode="numeric">
                    <div id="mc-personnel-units-required-note" class="mc-personnel-input-note">Disabled in All Stations mode. Select the target-units mode to enter a stopping target.</div>

                    <label style="margin-top:6px; display:block;"><b>Start From:</b></label>
                    <select id="mc-personnel-startfrom">
                        <option value="">Refresh stations first</option>
                    </select>
                </div>

                <div class="mc-namer-buttons">
                    <button id="mc-personnel-refresh">Refresh Stations</button>
                    <button id="mc-personnel-build-register" title="Scan every Police, Aviation and EOD station and rebuild the exact vehicle training register without changing any personnel assignments.">Build Personnel Register</button>
                    <button id="mc-personnel-start">Start</button>
                    <button id="mc-personnel-pause">Pause</button>
                    <button id="mc-personnel-stop">Stop</button>
                    <button id="mc-personnel-view-station-report">View Station Report</button>
                    <button id="mc-personnel-copy-station">Copy Station Report</button>
                    <button id="mc-personnel-copy">Copy Overall Report</button>
                    <button id="mc-personnel-debug">Debug: OFF</button>
                    <button id="mc-personnel-clear">Clear Log</button>
                </div>

                <div class="mc-namer-section">
                    <div><b>Status:</b> <span id="mc-personnel-status">Idle</span></div>
                    <div><b>Station:</b> <span id="mc-personnel-current">None</span></div>
                    <div><b>Vehicle:</b> <span id="mc-personnel-vehicle">None</span></div>
                    <div><b>Station progress:</b> <span id="mc-personnel-progress">0 / 0</span></div>
                    <div><b>Stations completed:</b> <span id="mc-personnel-completed">0</span></div>
                    <div><b>Vehicles checked:</b> <span id="mc-personnel-vehicles">0</span></div>
                    <div><b id="mc-personnel-units-fulfilled-label">Units fulfilled:</b> <span id="mc-personnel-units-fulfilled">0 / All</span></div>
                    <div><b>Planned / assigned:</b> <span id="mc-personnel-assigned">0</span></div>
                    <div><b>Need training:</b> <span id="mc-personnel-training-shortfall">0</span></div>
                    <div><b>Unfilled positions:</b> <span id="mc-personnel-assignment-shortfall">0</span></div>
                </div>

                <div id="mc-personnel-training-shortfall-section" class="mc-namer-section mc-personnel-training-shortfall-section" hidden>
                    <div class="mc-personnel-training-shortfall-heading">
                        ⚠ Stations needing additional qualified personnel:
                        <span id="mc-personnel-training-shortfall-station-count">0</span>
                    </div>
                    <div class="mc-personnel-training-shortfall-note">
                        This only shows genuine training shortages. Assignment or verification problems are kept separate.
                    </div>
                    <div id="mc-personnel-training-shortfall-list" class="mc-personnel-training-shortfall-list"></div>
                </div>

                <div class="mc-namer-section mc-personnel-report-options">
                    <b>Report display:</b>
                    <div class="mc-personnel-report-toggle-grid">
                        <label class="mc-personnel-report-toggle">
                            <input id="mc-personnel-show-station-report" type="checkbox" checked>
                            <span>Latest station report</span>
                        </label>
                        <label class="mc-personnel-report-toggle">
                            <input id="mc-personnel-show-overall-report" type="checkbox" checked>
                            <span>Overall run report</span>
                        </label>
                    </div>
                    <div class="mc-personnel-report-note">The short status and shortfall figures above always remain visible.</div>
                </div>

                <div id="mc-personnel-after-action-section" class="mc-namer-section mc-personnel-report-section">
                    <b>Latest Station After-Action Report</b>
                    <pre id="mc-personnel-after-action">Run a station preview or assignment to create the station report.</pre>
                </div>

                <div id="mc-personnel-overall-report-section" class="mc-namer-section mc-personnel-report-section">
                    <b>Overall Run Report</b>
                    <pre id="mc-personnel-report">Run a preview or assignment to create the overall report.</pre>
                </div>

                <div class="mc-personnel-log-heading">Live Activity Log</div>
                <div id="mc-personnel-log"></div>
            </div>
            </div>
        `;

        document.body.appendChild(panel);
        ensureSingleNamingToolsPanel(panel);

        const style = document.createElement('style');
        style.dataset.mcNamerStyle = 'true';
        style.textContent = `
            #mc-namer-panel {
                position: fixed;
                top: 90px;
                right: 20px;
                width: 470px;
                max-height: 760px;
                background: #1f2933;
                color: #f5f5f5;
                z-index: 999999;
                border-radius: 8px;
                box-shadow: 0 4px 16px rgba(0,0,0,0.35);
                font-family: Arial, sans-serif;
                font-size: 12px;
                overflow: hidden;
                display: flex;
                flex-direction: column;
                max-height: min(760px, calc(100vh - 20px));
            }

            #mc-namer-body {
                min-height: 0;
                overflow-y: auto;
                overflow-x: hidden;
                overscroll-behavior: contain;
                scrollbar-gutter: stable;
            }

            #mc-namer-header {
                background: #0d6efd;
                padding: 7px 8px 7px 10px;
                font-weight: bold;
                font-size: 14px;
                cursor: move;
                user-select: none;
                display: flex;
                align-items: center;
                justify-content: space-between;
                gap: 8px;
                min-height: 34px;
            }

            #mc-namer-header-title {
                min-width: 0;
                overflow: hidden;
                white-space: nowrap;
                text-overflow: ellipsis;
            }

            #mc-namer-collapse {
                flex: 0 0 26px;
                width: 26px;
                height: 24px;
                padding: 0;
                border: 1px solid rgba(255,255,255,0.45);
                border-radius: 5px;
                background: rgba(0,0,0,0.18);
                color: #ffffff;
                font-size: 18px;
                font-weight: bold;
                line-height: 20px;
                cursor: pointer;
            }

            #mc-namer-collapse:hover,
            #mc-namer-collapse:focus-visible {
                background: rgba(255,255,255,0.20);
                outline: none;
            }

            #mc-namer-panel.mc-namer-collapsed {
                width: 290px;
                max-height: none;
            }

            #mc-namer-panel.mc-namer-collapsed #mc-namer-body {
                display: none;
            }

            .mc-namer-tabs {
                display: flex;
                gap: 0;
                background: #0b1220;
                border-bottom: 1px solid #374151;
                position: sticky;
                top: 0;
                z-index: 20;
            }

            .mc-namer-tab {
                flex: 1;
                border: 0;
                border-right: 1px solid #374151;
                border-radius: 0;
                padding: 8px 6px;
                background: #1f2937;
                color: #cbd5e1;
                cursor: pointer;
                font-size: 12px;
                font-weight: bold;
            }

            .mc-namer-tab:last-child {
                border-right: 0;
            }

            .mc-namer-tab:hover {
                background: #273449;
                color: #ffffff;
            }

            .mc-namer-tab.active {
                background: #0d6efd;
                color: #ffffff;
                box-shadow: inset 0 -3px 0 #93c5fd;
            }

            .mc-tool-view {
                background: #111827;
            }

            .mc-namer-section {
                padding: 8px 10px;
                background: #111827;
                border-bottom: 1px solid #374151;
                line-height: 1.5;
            }

            #mc-namer-startfrom,
            #mc-namer-station-type,
            #mc-namer-unit-class,
            #mc-namer-mode,
            #mc-station-startfrom,
            #mc-station-type,
            #mc-station-mode,
            #mc-station-action,
            #mc-personnel-service,
            #mc-personnel-profile,
            #mc-personnel-startfrom,
            #mc-personnel-mode,
            #mc-personnel-action,
            #mc-personnel-units-required {
                width: 100%;
                margin-top: 4px;
                padding: 5px;
                color: #111;
                border-radius: 4px;
                border: 1px solid #555;
            }

            .mc-personnel-input-note {
                margin-top: 4px;
                color: #9ca3af;
                font-size: 10px;
                line-height: 1.3;
            }

            .mc-namer-buttons {
                padding: 8px;
                display: flex;
                gap: 5px;
                flex-wrap: wrap;
                background: #111827;
                border-bottom: 1px solid #374151;
            }

            .mc-namer-buttons button {
                border: 0;
                border-radius: 4px;
                padding: 5px 8px;
                cursor: pointer;
                font-size: 12px;
            }

            #mc-namer-refresh,
            #mc-station-refresh,
            #mc-personnel-refresh { background: #6c757d; color: white; }

            #mc-namer-start,
            #mc-station-start,
            #mc-personnel-start { background: #198754; color: white; }

            #mc-namer-pause,
            #mc-station-pause,
            #mc-personnel-pause { background: #ffc107; color: #111; }

            #mc-namer-stop,
            #mc-station-stop,
            #mc-personnel-stop { background: #dc3545; color: white; }

            #mc-personnel-copy,
            #mc-personnel-copy-station { background: #7c3aed; color: white; }

            #mc-personnel-view-station-report { background: #2563eb; color: white; }

            #mc-namer-debug,
            #mc-station-debug,
            #mc-personnel-debug { background: #0dcaf0; color: #111; }

            #mc-namer-clear,
            #mc-station-clear,
            #mc-personnel-clear { background: #f8f9fa; color: #111; }

            #mc-namer-log,
            #mc-station-log,
            #mc-personnel-log {
                padding: 8px 10px;
                max-height: 350px;
                overflow-y: auto;
                background: #0b1220;
                font-family: Consolas, monospace;
                white-space: pre-wrap;
                line-height: 1.4;
            }

            .mc-personnel-navigation-section {
                background: linear-gradient(180deg, #111827 0%, #0f172a 100%);
            }

            .mc-personnel-navigation-title {
                margin-bottom: 7px;
                color: #bfdbfe;
                font-size: 12px;
                font-weight: bold;
                letter-spacing: 0.2px;
            }

            .mc-personnel-profile-banner {
                margin: 7px 0;
                padding: 6px 8px;
                border: 1px solid #374151;
                border-radius: 5px;
                background: #0b1220;
                font-weight: bold;
                line-height: 1.3;
            }

            .mc-personnel-profile-banner.is-live {
                border-color: #22c55e;
                background: rgba(20,83,45,0.32);
                color: #bbf7d0;
            }

            .mc-personnel-profile-banner.is-preview {
                border-color: #f59e0b;
                background: rgba(120,53,15,0.28);
                color: #fde68a;
            }

            .mc-personnel-policy-summary {
                margin-top: 7px;
                padding: 7px 8px;
                border-left: 4px solid #3b82f6;
                border-radius: 4px;
                background: rgba(30,64,175,0.16);
                color: #dbeafe;
                font-size: 11px;
                line-height: 1.35;
            }

            .mc-personnel-policy-summary strong {
                color: #ffffff;
            }

            #mc-personnel-start:disabled,
            #mc-personnel-refresh:disabled,
            #mc-personnel-mode:disabled,
            #mc-personnel-action:disabled,
            #mc-personnel-startfrom:disabled {
                cursor: not-allowed;
                opacity: 0.45;
                filter: grayscale(0.35);
            }

            .mc-personnel-fixed-grid {
                display: grid;
                grid-template-columns: repeat(3, minmax(0, 1fr));
                gap: 6px;
            }

            .mc-personnel-fixed-grid > div {
                padding: 6px;
                border: 1px solid #374151;
                border-radius: 5px;
                background: #0b1220;
                text-align: center;
            }

            .mc-personnel-training-shortfall-section {
                border-left: 5px solid #ef4444;
                background: #2b1015;
                box-shadow: inset 0 0 0 1px rgba(239,68,68,0.28);
            }

            .mc-personnel-training-shortfall-heading {
                color: #fecaca;
                font-weight: bold;
                font-size: 12px;
            }

            .mc-personnel-training-shortfall-note {
                margin-top: 3px;
                color: #fca5a5;
                font-size: 10px;
                line-height: 1.3;
            }

            .mc-personnel-training-shortfall-list {
                display: grid;
                gap: 5px;
                max-height: 145px;
                margin-top: 7px;
                overflow-y: auto;
                overscroll-behavior: contain;
                scrollbar-gutter: stable;
            }

            .mc-personnel-training-shortfall-row {
                display: grid;
                grid-template-columns: minmax(0, 1fr) auto;
                gap: 8px;
                align-items: center;
                padding: 6px 7px;
                border: 1px solid rgba(248,113,113,0.45);
                border-radius: 5px;
                background: rgba(127,29,29,0.34);
            }

            .mc-personnel-training-shortfall-name {
                min-width: 0;
                color: #fee2e2;
                font-weight: bold;
                overflow-wrap: anywhere;
            }

            .mc-personnel-training-shortfall-value {
                color: #ffffff;
                font-weight: bold;
                white-space: nowrap;
            }

            a.mc-personnel-training-shortfall-station {
                border-left: 5px solid #ef4444 !important;
                box-shadow: inset 0 0 0 1px rgba(239,68,68,0.42) !important;
                background-color: rgba(127,29,29,0.24) !important;
            }

            .mc-personnel-report-options {
                padding-top: 7px;
                padding-bottom: 7px;
            }

            .mc-personnel-report-toggle-grid {
                display: grid;
                grid-template-columns: repeat(2, minmax(0, 1fr));
                gap: 6px;
                margin-top: 6px;
            }

            .mc-personnel-report-toggle {
                display: flex;
                align-items: center;
                gap: 6px;
                min-width: 0;
                padding: 6px 7px;
                border: 1px solid #374151;
                border-radius: 5px;
                background: #0b1220;
                cursor: pointer;
                user-select: none;
            }

            .mc-personnel-report-toggle input {
                flex: 0 0 auto;
                margin: 0;
                cursor: pointer;
            }

            .mc-personnel-report-toggle span {
                min-width: 0;
                line-height: 1.25;
            }

            .mc-personnel-report-note {
                margin-top: 5px;
                color: #9ca3af;
                font-size: 11px;
            }

            .mc-personnel-report-section {
                padding-bottom: 8px;
                scroll-margin-top: 42px;
            }

            .mc-personnel-report-section[hidden] {
                display: none !important;
            }

            #mc-personnel-report,
            #mc-personnel-after-action {
                margin: 6px 0 0;
                min-height: 130px;
                max-height: 280px;
                overflow-y: scroll;
                overflow-x: auto;
                overscroll-behavior: contain;
                scrollbar-gutter: stable both-edges;
                padding: 8px;
                border: 1px solid #374151;
                border-radius: 5px;
                background: #070d18;
                color: #d1fae5;
                font: 11px/1.4 Consolas, monospace;
                white-space: pre-wrap;
                overflow-wrap: anywhere;
                user-select: text;
            }

            #mc-personnel-after-action {
                color: #e0f2fe;
                border-color: #2563eb;
            }

            #mc-personnel-log {
                max-height: 220px;
                overflow-y: scroll;
                overscroll-behavior: contain;
                scrollbar-gutter: stable;
            }

            .mc-personnel-log-heading {
                padding: 7px 10px;
                background: #111827;
                border-bottom: 1px solid #374151;
                font-weight: bold;
            }

            .mc-log-info { color: #93c5fd; }
            .mc-log-station { color: #bfdbfe; font-weight: bold; margin-top: 8px; }
            .mc-log-before { color: #fca5a5; }
            .mc-log-after { color: #86efac; }
            .mc-log-debug { color: #facc15; }
            .mc-log-error { color: #f87171; font-weight: bold; }
            .mc-log-done { color: #22c55e; font-weight: bold; }

            #mc-namer-panel.mc-ios-safari {
                top: calc(8px + env(safe-area-inset-top, 0px));
                right: calc(8px + env(safe-area-inset-right, 0px));
                left: calc(8px + env(safe-area-inset-left, 0px));
                width: auto;
                max-width: none;
                max-height: calc(
                    100vh
                    - 16px
                    - env(safe-area-inset-top, 0px)
                    - env(safe-area-inset-bottom, 0px)
                );
                -webkit-transform: translateZ(0);
            }

            @supports (height: 100dvh) {
                #mc-namer-panel.mc-ios-safari {
                    max-height: calc(
                        100dvh
                        - 16px
                        - env(safe-area-inset-top, 0px)
                        - env(safe-area-inset-bottom, 0px)
                    );
                }
            }

            #mc-namer-panel.mc-ios-safari.mc-namer-collapsed {
                width: auto;
            }

            #mc-namer-panel.mc-ios-safari #mc-namer-header {
                cursor: grab;
                touch-action: none;
                -webkit-user-select: none;
            }

            #mc-namer-panel.mc-ios-safari #mc-namer-header:active {
                cursor: grabbing;
            }

            #mc-namer-panel.mc-ios-safari #mc-namer-body,
            #mc-namer-panel.mc-ios-safari #mc-namer-log,
            #mc-namer-panel.mc-ios-safari #mc-station-log,
            #mc-namer-panel.mc-ios-safari #mc-personnel-log,
            #mc-namer-panel.mc-ios-safari #mc-personnel-report,
            #mc-namer-panel.mc-ios-safari #mc-personnel-after-action {
                -webkit-overflow-scrolling: touch;
            }

            #mc-namer-panel.mc-ios-safari .mc-namer-tab {
                min-height: 42px;
                padding: 7px 4px;
                font-size: 11px;
                line-height: 1.2;
            }

            #mc-namer-panel.mc-ios-safari .mc-namer-buttons button,
            #mc-namer-panel.mc-ios-safari select,
            #mc-namer-panel.mc-ios-safari input {
                min-height: 36px;
                font-size: 16px;
            }

        `;

        document.head.appendChild(style);

        document.querySelector('#mc-tab-unit').onclick = () => switchToolTab('unit');
        document.querySelector('#mc-tab-station').onclick = () => switchToolTab('station');
        document.querySelector('#mc-tab-personnel').onclick = () => switchToolTab('personnel');
        document.querySelector('#mc-namer-collapse').onclick = event => {
            event.preventDefault();
            event.stopPropagation();
            togglePanelCollapsed();
        };
        document.querySelector('#mc-namer-collapse').onmousedown = event => {
            event.stopPropagation();
        };

        document.querySelector('#mc-namer-refresh').onclick = refreshStations;
        document.querySelector('#mc-namer-start').onclick = startRun;
        document.querySelector('#mc-namer-pause').onclick = togglePause;
        document.querySelector('#mc-namer-stop').onclick = stopRun;
        document.querySelector('#mc-namer-debug').onclick = toggleDebug;
        document.querySelector('#mc-namer-clear').onclick = clearLog;
        document.querySelector('#mc-namer-station-type').onchange = handleUnitStationTypeChange;
        document.querySelector('#mc-namer-unit-class').onchange = handleUnitClassChange;
        populateUnitClassDropdown();

        document.querySelector('#mc-station-refresh').onclick = refreshStationNamingStations;
        document.querySelector('#mc-station-start').onclick = startStationNamingRun;
        document.querySelector('#mc-station-pause').onclick = toggleStationNamingPause;
        document.querySelector('#mc-station-stop').onclick = stopStationNamingRun;
        document.querySelector('#mc-station-debug').onclick = toggleStationDebug;
        document.querySelector('#mc-station-clear').onclick = clearStationLog;
        document.querySelector('#mc-station-type').onchange = populateStationNamingStartDropdown;
        document.querySelector('#mc-station-startfrom').onchange = updateStationNamingSelectionPreview;
        document.querySelector('#mc-station-mode').onchange = () => {
            STATION_STATE.mode = document.querySelector('#mc-station-mode')?.value || 'all';
        };
        document.querySelector('#mc-station-action').onchange = () => {
            STATION_STATE.action = document.querySelector('#mc-station-action')?.value || 'preview';
        };

        document.querySelector('#mc-personnel-service').onchange = handlePersonnelServiceChange;
        document.querySelector('#mc-personnel-profile').onchange = handlePersonnelProfileChange;
        document.querySelector('#mc-personnel-units-required').onchange = handlePersonnelUnitsRequiredChange;
        document.querySelector('#mc-personnel-refresh').onclick = refreshPersonnelStations;
        document.querySelector('#mc-personnel-build-register').onclick = buildPersonnelTrainingRegisterOneClick;
        document.querySelector('#mc-personnel-start').onclick = startPersonnelRun;
        document.querySelector('#mc-personnel-pause').onclick = togglePersonnelPause;
        document.querySelector('#mc-personnel-stop').onclick = stopPersonnelRun;
        document.querySelector('#mc-personnel-view-station-report').onclick = showAndViewPersonnelStationReport;
        document.querySelector('#mc-personnel-copy-station').onclick = copyPersonnelStationReport;
        document.querySelector('#mc-personnel-copy').onclick = copyPersonnelReport;
        document.querySelector('#mc-personnel-debug').onclick = togglePersonnelDebug;
        document.querySelector('#mc-personnel-clear').onclick = clearPersonnelLog;
        document.querySelector('#mc-personnel-startfrom').onchange = updatePersonnelSelectionPreview;
        document.querySelector('#mc-personnel-mode').onchange =
            handlePersonnelModeChange;
        document.querySelector('#mc-personnel-action').onchange = () => {
            PERSONNEL_STATE.action = document.querySelector('#mc-personnel-action')?.value || 'preview';
        };
        document.querySelector('#mc-personnel-show-station-report').onchange = () => updatePersonnelReportVisibility(true);
        document.querySelector('#mc-personnel-show-overall-report').onchange = () => updatePersonnelReportVisibility(true);

        initialisePersonnelProfileNavigation();
        initialisePersonnelReportVisibility();
        makePanelDraggable(panel, document.querySelector('#mc-namer-header'));
        installToolViewportGuard(panel);
        installSingleNamingToolsPanelGuard(panel);

        let savedTab = 'unit';
        let savedCollapsed = false;
        try {
            savedTab = localStorage.getItem(ACTIVE_TAB_STORAGE_KEY) || 'unit';
            savedCollapsed = localStorage.getItem(COLLAPSED_STORAGE_KEY) === 'true';
        } catch (e) {}

        switchToolTab(savedTab === 'station' ? 'station' : savedTab === 'personnel' ? 'personnel' : 'unit', true);
        setPanelCollapsed(savedCollapsed, false);
    }

    function getPersonnelServiceDefinition(serviceId = PERSONNEL_STATE.service) {
        return PERSONNEL_SERVICE_DEFINITIONS[serviceId]
            || PERSONNEL_SERVICE_DEFINITIONS.medical;
    }

    function getPersonnelProfileDefinition(serviceId = PERSONNEL_STATE.service, profileId = PERSONNEL_STATE.profile) {
        const service = getPersonnelServiceDefinition(serviceId);
        return service.profiles.find(profile => profile.id === profileId)
            || service.profiles[0];
    }

    function isLivePersonnelProfile() {
        return getPersonnelProfileDefinition()?.live === true;
    }

    function normalisePersonnelUnitsRequired(value) {
        const parsed = Number.parseInt(String(value ?? '').trim(), 10);
        if (!Number.isFinite(parsed) || parsed < 0) return 0;
        return Math.min(9999, parsed);
    }

    function isPersonnelPerStationTargetMode() {
        return (
            PERSONNEL_STATE.mode === 'target'
            && PERSONNEL_STATE.unitsRequired > 0
        );
    }

    function getPersonnelUnitsRemaining() {
        return isPersonnelPerStationTargetMode()
            ? PERSONNEL_STATE.unitsRequired
            : Number.POSITIVE_INFINITY;
    }


    function formatPersonnelUnitsFulfilled() {
        if (isPersonnelPerStationTargetMode()) {
            const target = PERSONNEL_STATE.unitsRequired;
            const latestFulfilled = PERSONNEL_STATE.lastStationReport
                && !PERSONNEL_STATE.lastStationReport.error
                    ? Math.min(
                        target,
                        Number(
                            PERSONNEL_STATE.lastStationReport.fulfilledUnits
                            || 0
                        )
                    )
                    : 0;

            return `${PERSONNEL_STATE.stationsTargetMet} / ${PERSONNEL_STATE.completedStations} stations met | latest ${latestFulfilled}/${target}`;
        }

        return `${PERSONNEL_STATE.unitsFulfilled} / All`;
    }

    function handlePersonnelUnitsRequiredChange() {
        const input =
            document.querySelector(
                '#mc-personnel-units-required'
            );

        if (!input) return;

        if (PERSONNEL_STATE.running) {
            input.value =
                String(
                    PERSONNEL_STATE
                        .configuredUnitsRequired ||
                    0
                );

            personnelLog(
                'Stop Personnel Assignment before changing Units required.',
                'error'
            );

            return;
        }

        const configuredTarget =
            normalisePersonnelUnitsRequired(
                input.value
            );

        PERSONNEL_STATE
            .configuredUnitsRequired =
                configuredTarget;

        PERSONNEL_STATE.unitsRequired =
            0;

        PERSONNEL_STATE.unitsFulfilled =
            0;

        PERSONNEL_STATE.unitTargetReached =
            false;

        input.value =
            String(configuredTarget);

        try {
            localStorage.setItem(
                PERSONNEL_UNITS_REQUIRED_STORAGE_KEY,
                String(configuredTarget)
            );
        } catch (_error) {}

        setPersonnelUiValue(
            'unitsFulfilled',
            configuredTarget > 0
                ? `0 / ${configuredTarget}`
                : '0 / target not set'
        );

        personnelLog(
            configuredTarget > 0
                ? `Each-station target is configured for ${configuredTarget} fully staffed unit(s).`
                : 'Each-station target has not been entered yet.',
            'debug'
        );
    }

    function updatePersonnelModeUi() {
        const modeSelect =
            document.querySelector(
                '#mc-personnel-mode'
            );

        const input =
            document.querySelector(
                '#mc-personnel-units-required'
            );

        const note =
            document.querySelector(
                '#mc-personnel-units-required-note'
            );

        const live =
            isLivePersonnelProfile();

        const mode =
            modeSelect?.value ||
            PERSONNEL_STATE.mode ||
            'all';

        PERSONNEL_STATE.mode =
            mode;

        const targetMode =
            mode === 'target';

        const fulfilledLabel =
            document.querySelector(
                '#mc-personnel-units-fulfilled-label'
            );

        if (fulfilledLabel) {
            fulfilledLabel.textContent =
                targetMode
                    ? 'Station targets met:'
                    : 'Units fulfilled:';
        }

        if (input) {
            input.disabled =
                !live ||
                !targetMode;

            input.value =
                targetMode
                    ? String(
                        PERSONNEL_STATE
                            .configuredUnitsRequired ||
                        0
                    )
                    : '0';
        }

        if (note) {
            note.textContent =
                targetMode
                    ? 'Enter the number of fully staffed units required at every station. Existing covered units count first; only the missing units are topped up.'
                    : mode === 'single'
                        ? 'Selected Station mode scans every matching unit at that one station. Units required is not used.'
                        : 'All Stations mode always scans every relevant station from the selected start point. Units required is not used.';
        }

        if (
            !PERSONNEL_STATE.running
        ) {
            setPersonnelUiValue(
                'unitsFulfilled',
                targetMode &&
                PERSONNEL_STATE
                    .configuredUnitsRequired >
                    0
                    ? `0 / ${PERSONNEL_STATE.configuredUnitsRequired}`
                    : '0 / All'
            );
        }
    }

    function handlePersonnelModeChange() {
        if (PERSONNEL_STATE.running) {
            const select =
                document.querySelector(
                    '#mc-personnel-mode'
                );

            if (select) {
                select.value =
                    PERSONNEL_STATE.mode ||
                    'all';
            }

            personnelLog(
                'Stop Personnel Assignment before changing Mode.',
                'error'
            );

            return;
        }

        PERSONNEL_STATE.mode =
            document.querySelector(
                '#mc-personnel-mode'
            )?.value ||
            'all';

        PERSONNEL_STATE.unitsRequired =
            0;

        PERSONNEL_STATE.unitsFulfilled =
            0;

        PERSONNEL_STATE.unitTargetReached =
            false;

        updatePersonnelModeUi();

        const modeMessage =
            PERSONNEL_STATE.mode ===
                'target'
                ? 'Mode set to enforce the Units required target independently at every station.'
                : PERSONNEL_STATE.mode ===
                    'single'
                    ? 'Mode set to Selected station only.'
                    : 'Mode set to All relevant stations. Every station in scope will be scanned.';

        personnelLog(
            modeMessage,
            'debug'
        );
    }

    function initialisePersonnelProfileNavigation() {
        const serviceSelect = document.querySelector('#mc-personnel-service');
        if (!serviceSelect) return;

        let savedService = 'medical';
        let savedProfile = 'critical_care';
        let savedUnitsRequired = 0;

        try {
            savedService = localStorage.getItem(PERSONNEL_SERVICE_STORAGE_KEY) || 'medical';
            savedProfile = localStorage.getItem(PERSONNEL_PROFILE_STORAGE_KEY) || 'critical_care';
            savedUnitsRequired = normalisePersonnelUnitsRequired(localStorage.getItem(PERSONNEL_UNITS_REQUIRED_STORAGE_KEY) || 0);
        } catch (_error) {}

        // Migrate the two service options that were combined in v4.1.2.
        if (savedService === 'mountain') savedService = 'coastguard';
        if (savedService === 'airport') savedService = 'fire';
        if (!PERSONNEL_SERVICE_DEFINITIONS[savedService]) savedService = 'medical';

        PERSONNEL_STATE.service = savedService;
        PERSONNEL_STATE.profile =
            savedProfile;

        PERSONNEL_STATE
            .configuredUnitsRequired =
                savedUnitsRequired;

        PERSONNEL_STATE.unitsRequired =
            0;

        PERSONNEL_STATE.unitsFulfilled =
            0;

        PERSONNEL_STATE.mode =
            document.querySelector(
                '#mc-personnel-mode'
            )?.value ||
            'all';

        serviceSelect.value =
            savedService;

        populatePersonnelProfileSelect(
            savedProfile
        );

        updatePersonnelProfileUi(
            false
        );

        updatePersonnelModeUi();
    }

    function populatePersonnelProfileSelect(preferredProfileId = '') {
        const select = document.querySelector('#mc-personnel-profile');
        if (!select) return;

        const service = getPersonnelServiceDefinition();
        select.innerHTML = '';

        service.profiles.forEach(profile => {
            const option = document.createElement('option');
            option.value = profile.id;
            option.textContent = `${profile.label}${profile.live ? ' — LIVE' : ' — UI preview'}`;
            select.appendChild(option);
        });

        const validPreferred = service.profiles.some(profile => profile.id === preferredProfileId)
            ? preferredProfileId
            : service.profiles[0]?.id || '';

        PERSONNEL_STATE.profile = validPreferred;
        select.value = validPreferred;
    }

    function handlePersonnelServiceChange() {
        if (PERSONNEL_STATE.running) {
            personnelLog('Stop Personnel Assignment before changing Service.', 'error');
            const select = document.querySelector('#mc-personnel-service');
            if (select) select.value = PERSONNEL_STATE.service;
            return;
        }

        PERSONNEL_STATE.service = document.querySelector('#mc-personnel-service')?.value || 'medical';
        populatePersonnelProfileSelect('');
        updatePersonnelProfileUi(true);
    }

    function handlePersonnelProfileChange() {
        if (PERSONNEL_STATE.running) {
            personnelLog('Stop Personnel Assignment before changing Training profile.', 'error');
            const select = document.querySelector('#mc-personnel-profile');
            if (select) select.value = PERSONNEL_STATE.profile;
            return;
        }

        PERSONNEL_STATE.profile = document.querySelector('#mc-personnel-profile')?.value || 'critical_care';
        updatePersonnelProfileUi(true);
    }

    function updatePersonnelProfileUi(save = true) {
        const service = getPersonnelServiceDefinition();
        const profile = getPersonnelProfileDefinition();
        const live = isLivePersonnelProfile();

        const training = document.querySelector('#mc-personnel-profile-training');
        const vehicle = document.querySelector('#mc-personnel-profile-vehicle');
        const requirement = document.querySelector('#mc-personnel-profile-requirement');
        const policy = document.querySelector('#mc-personnel-policy-summary');
        const banner = document.querySelector('#mc-personnel-profile-banner');
        const modeAll = document.querySelector('#mc-personnel-mode-all-option');
        const start = document.querySelector('#mc-personnel-start');
        const refresh = document.querySelector('#mc-personnel-refresh');
        const mode = document.querySelector('#mc-personnel-mode');
        const action = document.querySelector('#mc-personnel-action');
        const unitsRequired = document.querySelector('#mc-personnel-units-required');
        const startFrom = document.querySelector('#mc-personnel-startfrom');

        if (training) training.textContent = profile.label;
        if (vehicle) vehicle.textContent = profile.vehicle;
        if (requirement) requirement.textContent = profile.requirement;
        if (policy) {
            policy.innerHTML = `<strong>${service.icon} ${service.label} policy:</strong> ${profile.policy}`;
        }

        if (banner) {
            banner.classList.toggle('is-live', live);
            banner.classList.toggle('is-preview', !live);
            banner.textContent = live
                ? '● LIVE PROFILE — the selected assignment engine is enabled.'
                : '◐ UI PREVIEW ONLY — assignment controls are safely disabled for this profile.';
        }

        if (modeAll) {
            modeAll.textContent = live
                ? `All ${getPersonnelStationScopeLabel()} from selected start point`
                : `All relevant ${service.label} stations from selected start point`;
        }

        [start, refresh, mode, action, startFrom].forEach(control => {
            if (control) control.disabled = !live;
        });

        if (unitsRequired) {
            unitsRequired.disabled =
                !live ||
                (
                    document.querySelector(
                        '#mc-personnel-mode'
                    )?.value ||
                    'all'
                ) !== 'target';
        }

        if (start) {
            start.title = live
                ? 'Start the selected Personnel Assignment profile'
                : 'This profile is a UI preview and cannot make assignments yet';
        }

        if (live) {
            setPersonnelUiValue('status', PERSONNEL_STATE.filteredStations.length ? 'Ready' : 'Refresh required');
        } else {
            setPersonnelUiValue('status', 'Profile UI preview');
            setPersonnelUiValue('vehicle', 'Not enabled');
        }

        if (save) {
            PERSONNEL_STATE.stations = [];
            PERSONNEL_STATE.filteredStations = [];
            PERSONNEL_STATE.queue = [];
            PERSONNEL_STATE.selectedHref = '';
            PERSONNEL_STATE.unitsFulfilled = 0;
            PERSONNEL_STATE.unitTargetReached = false;
            setPersonnelUiValue('unitsFulfilled', PERSONNEL_STATE.unitsRequired > 0 ? `0 / ${PERSONNEL_STATE.unitsRequired}` : '0 / All');
            populatePersonnelStartDropdown();
            setPersonnelUiValue('status', live ? 'Refresh required' : 'Profile UI preview');
            setPersonnelUiValue('vehicle', live ? 'None' : 'Not enabled');

            try {
                localStorage.setItem(PERSONNEL_SERVICE_STORAGE_KEY, PERSONNEL_STATE.service);
                localStorage.setItem(PERSONNEL_PROFILE_STORAGE_KEY, PERSONNEL_STATE.profile);
            } catch (_error) {}

            personnelLog(`${service.icon} Service: ${service.label} | Training profile: ${profile.label}${live ? ' (LIVE)' : ' (UI preview only)'}`, live ? 'info' : 'debug');
        }

        updatePersonnelModeUi();
    }

    function initialisePersonnelReportVisibility() {
        const stationCheckbox = document.querySelector('#mc-personnel-show-station-report');
        const overallCheckbox = document.querySelector('#mc-personnel-show-overall-report');
        if (!stationCheckbox || !overallCheckbox) return;

        let showStation = true;
        let showOverall = true;

        try {
            showStation = localStorage.getItem(PERSONNEL_STATION_REPORT_VISIBLE_KEY) !== 'false';
            showOverall = localStorage.getItem(PERSONNEL_OVERALL_REPORT_VISIBLE_KEY) !== 'false';
        } catch (_error) {}

        stationCheckbox.checked = showStation;
        overallCheckbox.checked = showOverall;
        updatePersonnelReportVisibility(false);
    }

    function updatePersonnelReportVisibility(save = true) {
        const stationCheckbox = document.querySelector('#mc-personnel-show-station-report');
        const overallCheckbox = document.querySelector('#mc-personnel-show-overall-report');
        const stationSection = document.querySelector('#mc-personnel-after-action-section');
        const overallSection = document.querySelector('#mc-personnel-overall-report-section');

        if (!stationCheckbox || !overallCheckbox || !stationSection || !overallSection) return;

        const showStation = Boolean(stationCheckbox.checked);
        const showOverall = Boolean(overallCheckbox.checked);

        stationSection.hidden = !showStation;
        overallSection.hidden = !showOverall;
        stationCheckbox.setAttribute('aria-expanded', showStation ? 'true' : 'false');
        overallCheckbox.setAttribute('aria-expanded', showOverall ? 'true' : 'false');

        if (save) {
            try {
                localStorage.setItem(PERSONNEL_STATION_REPORT_VISIBLE_KEY, showStation ? 'true' : 'false');
                localStorage.setItem(PERSONNEL_OVERALL_REPORT_VISIBLE_KEY, showOverall ? 'true' : 'false');
            } catch (_error) {}
        }
    }

    function showAndViewPersonnelStationReport() {
        const checkbox = document.querySelector('#mc-personnel-show-station-report');
        if (checkbox && !checkbox.checked) {
            checkbox.checked = true;
            updatePersonnelReportVisibility(true);
        }

        requestAnimationFrame(() => scrollPersonnelTo('mc-personnel-after-action-section'));
    }


    function togglePanelCollapsed() {
        const panel = document.querySelector('#mc-namer-panel');
        if (!panel) return;
        setPanelCollapsed(!panel.classList.contains('mc-namer-collapsed'));
    }

    function setPanelCollapsed(collapsed, save = true) {
        const panel = document.querySelector('#mc-namer-panel');
        const button = document.querySelector('#mc-namer-collapse');
        if (!panel || !button) return;

        panel.classList.toggle('mc-namer-collapsed', Boolean(collapsed));
        button.textContent = collapsed ? '+' : '−';
        button.setAttribute('aria-expanded', collapsed ? 'false' : 'true');
        button.title = collapsed ? 'Expand naming tools' : 'Collapse naming tools';

        if (save) {
            try {
                localStorage.setItem(COLLAPSED_STORAGE_KEY, collapsed ? 'true' : 'false');
            } catch (e) {}
        }
    }

    function switchToolTab(tabName, force = false) {
        const targetTab = ['unit', 'station', 'personnel'].includes(tabName) ? tabName : 'unit';
        const unitView = document.querySelector('#mc-unit-view');
        const stationView = document.querySelector('#mc-station-view');
        const personnelView = document.querySelector('#mc-personnel-view');
        const unitTab = document.querySelector('#mc-tab-unit');
        const stationTab = document.querySelector('#mc-tab-station');
        const personnelTab = document.querySelector('#mc-tab-personnel');
        const headerTitle = document.querySelector('#mc-namer-header-title');

        if (!unitView || !stationView || !personnelView || !unitTab || !stationTab || !personnelTab || !headerTitle) return;

        if (!force && STATE.running && targetTab !== 'unit') {
            log('Stop the Unit Naming Tool before switching tabs.', 'error');
            return;
        }

        if (!force && STATION_STATE.running && targetTab !== 'station') {
            stationLog('Stop the Station Naming Tool before switching tabs.', 'error');
            return;
        }

        if (!force && PERSONNEL_STATE.running && targetTab !== 'personnel') {
            personnelLog('Stop Personnel Assignment before switching tabs.', 'error');
            return;
        }

        const showUnit = targetTab === 'unit';
        const showStation = targetTab === 'station';
        const showPersonnel = targetTab === 'personnel';

        unitView.style.display = showUnit ? 'block' : 'none';
        stationView.style.display = showStation ? 'block' : 'none';
        personnelView.style.display = showPersonnel ? 'block' : 'none';

        unitTab.classList.toggle('active', showUnit);
        stationTab.classList.toggle('active', showStation);
        personnelTab.classList.toggle('active', showPersonnel);
        unitTab.setAttribute('aria-selected', showUnit ? 'true' : 'false');
        stationTab.setAttribute('aria-selected', showStation ? 'true' : 'false');
        personnelTab.setAttribute('aria-selected', showPersonnel ? 'true' : 'false');

        headerTitle.textContent = showUnit
            ? `🚒 Unit Naming Tool v${UNIT_VERSION}`
            : showStation
                ? `🏢 Station Naming Tool v${STATION_VERSION}`
                : `👥 Personnel Assignment v${PERSONNEL_VERSION}`;

        try {
            localStorage.setItem(ACTIVE_TAB_STORAGE_KEY, targetTab);
        } catch (e) {}
    }

    function refreshStationNamingStations() {
        if (PERSONNEL_STATE.running) {
            stationLog('Personnel Assignment is currently running. Stop it before refreshing Station Naming.', 'error');
            setStationUiValue('status', 'Blocked by Personnel Assignment');
            return;
        }

        if (STATE.running) {
            stationLog('Unit Naming is currently running. Stop it before refreshing Station Naming.', 'error');
            setStationUiValue('status', 'Blocked by Unit Naming');
            return;
        }

        if (STATION_STATE.running) {
            stationLog('Stop Station Naming before refreshing the station list.', 'error');
            return;
        }

        setStationUiValue('status', 'Refreshing stations...');
        stationLog('Refreshing station list and reading MissionChief building type IDs...', 'info');

        const stationEntries = getStationOverviewEntries();

        STATION_STATE.stations = stationEntries
            .map((entry, index) => {
                const typeInfo = getStationNamingTypeInfo(
                    entry.buildingTypeId,
                    entry.displayName
                );

                return {
                    index,
                    href: entry.href,
                    buildingId: entry.buildingId,
                    displayName: entry.displayName,
                    buildingTypeId: entry.buildingTypeId,
                    stationType: typeInfo.stationType,
                    suffix: typeInfo.suffix,
                    typeLabel: typeInfo.label
                };
            })
            .filter(station => station.href && station.buildingId);

        populateStationNamingStartDropdown();
        setStationUiValue('status', 'Ready');

        stationLog(`Stations found: ${STATION_STATE.stations.length}`, 'info');
        stationLog(`Matching filter: ${STATION_STATE.filteredStations.length}`, 'info');

        if (STATION_STATE.filteredStations.length) {
            stationLog(`First match: ${STATION_STATE.filteredStations[0].displayName}`, 'info');
            stationLog(`Last match : ${STATION_STATE.filteredStations[STATION_STATE.filteredStations.length - 1].displayName}`, 'info');
        }
    }

    function getStationNamingTypeInfo(buildingTypeId, displayName) {
        const name = cleanText(displayName).toUpperCase();

        // Airport fire stations share MissionChief's normal fire-station type IDs.
        // Use an explicit existing name marker only for this special case.
        if ((buildingTypeId === 0 || buildingTypeId === 18)
            && (/\bAIRPORT\b|\bAIRFIELD\b/.test(name) || /-AF\d*$/.test(name))) {
            return { stationType: 'AIRFIELD', suffix: '-AF', label: 'Airfield station' };
        }

        const mapped = STATION_BUILDING_TYPE_INFO[buildingTypeId];
        if (mapped) return mapped;

        const detectedType = detectStationType(displayName);
        const fallbackByType = {
            FIRE: { stationType: 'FIRE', suffix: '-FS', label: 'Fire station' },
            AMBULANCE: { stationType: 'AMBULANCE', suffix: '-AS', label: 'Ambulance station' },
            POLICE: { stationType: 'POLICE', suffix: '-PS', label: 'Police station' },
            RNLI: { stationType: 'RNLI', suffix: '-RNLI', label: 'RNLI / lifeboat station' },
            COASTGUARD: { stationType: 'COASTGUARD', suffix: '-CG', label: 'Coastguard station' },
            SAR: { stationType: 'SAR', suffix: '-SAR', label: 'Search and rescue station' },
            AIRFIELD: { stationType: 'AIRFIELD', suffix: '-AF', label: 'Airfield station' },
            EOD: { stationType: 'EOD', suffix: '-EOD', label: 'EOD / bomb disposal station' },
            RECOVERY: { stationType: 'RECOVERY', suffix: '-REC', label: 'Recovery station' }
        };

        if (detectedType === 'AIR') {
            return /POLICE/i.test(name)
                ? { stationType: 'AIR', suffix: '-PH', label: 'Police helicopter station' }
                : { stationType: 'AIR', suffix: '-AA', label: 'Air ambulance station' };
        }

        return fallbackByType[detectedType]
            || { stationType: 'OTHER', suffix: '', label: `Unsupported building type ${buildingTypeId ?? 'unknown'}` };
    }

    function populateStationNamingStartDropdown() {
        const select = document.querySelector('#mc-station-startfrom');
        if (!select) return;

        const selectedType = document.querySelector('#mc-station-type')?.value || 'ALL';

        STATION_STATE.filteredStations = STATION_STATE.stations.filter(station => {
            return selectedType === 'ALL' || station.stationType === selectedType;
        });

        select.innerHTML = '';

        if (!STATION_STATE.filteredStations.length) {
            select.innerHTML = '<option value="">No matching stations found</option>';
            STATION_STATE.selectedHref = '';
            setStationUiValue('current', 'None');
            setStationUiValue('progress', '0 / 0');
            return;
        }

        const firstOption = document.createElement('option');
        firstOption.value = STATION_STATE.filteredStations[0].href;
        firstOption.textContent = 'Start from first matching station';
        select.appendChild(firstOption);

        STATION_STATE.filteredStations.forEach(station => {
            const option = document.createElement('option');
            option.value = station.href;
            option.textContent = `${station.displayName} [${STATION_TYPES[station.stationType] || station.stationType} | type ${station.buildingTypeId ?? '?'}]`;
            select.appendChild(option);
        });

        STATION_STATE.selectedHref = select.value;
        setStationUiValue('progress', `0 / ${STATION_STATE.filteredStations.length}`);
        updateStationNamingSelectionPreview();
    }

    function updateStationNamingSelectionPreview() {
        const select = document.querySelector('#mc-station-startfrom');
        const selectedHref = select?.value || '';
        const station = STATION_STATE.filteredStations.find(item => item.href === selectedHref);

        STATION_STATE.selectedHref = selectedHref;
        setStationUiValue('current', station?.displayName || 'None');
        setStationUiValue('address', 'Not read yet');
        setStationUiValue('town', 'Not extracted yet');
        setStationUiValue('before', station?.displayName || 'None');
        setStationUiValue('after', 'Not generated yet');

        if (station) {
            stationDebug(`Selected: ${station.displayName} | href=${selectedHref} | building_type_id=${station.buildingTypeId} | rule=${station.typeLabel} ${station.suffix}`);
        }
    }

    function startStationNamingRun() {
        if (PERSONNEL_STATE.running) {
            stationLog('Personnel Assignment is currently running. Stop it before starting Station Naming.', 'error');
            setStationUiValue('status', 'Blocked by Personnel Assignment');
            return;
        }

        if (STATE.running) {
            stationLog('Unit Naming is currently running. Stop it before starting Station Naming.', 'error');
            setStationUiValue('status', 'Blocked by Unit Naming');
            return;
        }

        if (STATION_STATE.running) {
            stationLog('Station Naming is already running.', 'debug');
            return;
        }

        if (!STATION_STATE.filteredStations.length) {
            stationLog('No matching stations loaded. Press Refresh Stations first.', 'error');
            setStationUiValue('status', 'Refresh required');
            return;
        }

        const selectedHref = document.querySelector('#mc-station-startfrom')?.value || '';
        const startIndex = STATION_STATE.filteredStations.findIndex(station => station.href === selectedHref);

        if (startIndex < 0) {
            stationLog(`Selected start station not found: ${selectedHref || 'none'}`, 'error');
            setStationUiValue('status', 'Invalid start station');
            return;
        }

        STATION_STATE.mode = document.querySelector('#mc-station-mode')?.value || 'all';
        STATION_STATE.action = document.querySelector('#mc-station-action')?.value || 'preview';
        STATION_STATE.queue = STATION_STATE.mode === 'single'
            ? [STATION_STATE.filteredStations[startIndex]]
            : STATION_STATE.filteredStations.slice(startIndex);
        STATION_STATE.running = true;
        STATION_STATE.paused = false;
        STATION_STATE.stopped = false;
        STATION_STATE.stationIndex = 0;
        STATION_STATE.renamedCount = 0;
        STATION_STATE.skippedCount = 0;
        STATION_STATE.previewedCount = 0;
        STATION_STATE.activeIframe = null;

        document.querySelector('#mc-station-pause').textContent = 'Pause';
        updateStationCounters();
        setStationUiValue('progress', `0 / ${STATION_STATE.queue.length}`);
        setStationUiValue('status', STATION_STATE.action === 'save' ? 'Starting rename run' : 'Starting preview');

        stationLog(`Mode: ${STATION_STATE.mode === 'single' ? 'Selected station only' : 'All matching stations from selected start point'}`, 'info');
        stationLog(`Action: ${STATION_STATE.action === 'save' ? 'RENAME AND SAVE' : 'PREVIEW ONLY - no names will be saved'}`, STATION_STATE.action === 'save' ? 'after' : 'info');
        stationLog(`Starting from: ${STATION_STATE.queue[0]?.displayName || 'None'}`, 'info');

        processStationNamingQueue().catch(error => {
            stationLog(`Station Naming stopped after an unexpected error: ${error?.message || error}`, 'error');
            stationDebug(error?.stack || String(error));
            STATION_STATE.stopped = true;
            STATION_STATE.running = false;
            setStationUiValue('status', 'Error');
        });
    }

    function toggleStationNamingPause() {
        if (!STATION_STATE.running) {
            stationLog('Nothing is currently running.', 'debug');
            return;
        }

        STATION_STATE.paused = !STATION_STATE.paused;
        document.querySelector('#mc-station-pause').textContent = STATION_STATE.paused ? 'Resume' : 'Pause';
        setStationUiValue('status', STATION_STATE.paused ? 'Paused' : 'Running');
        stationLog(STATION_STATE.paused ? 'Paused. The current safe step will finish before waiting.' : 'Resumed.', 'debug');
    }

    function stopStationNamingRun() {
        if (!STATION_STATE.running) {
            stationLog('Nothing is currently running.', 'debug');
            return;
        }

        STATION_STATE.stopped = true;
        STATION_STATE.paused = false;
        document.querySelector('#mc-station-pause').textContent = 'Pause';
        setStationUiValue('status', 'Stopping...');

        for (const controller of STATION_STATE.activeControllers) {
            try {
                controller.abort();
            } catch (_error) {}
        }
        STATION_STATE.activeControllers.clear();

        stationLog('Stop requested. Active station requests were cancelled and no further station will be saved.', 'error');
    }

    async function processStationNamingQueue() {
        try {
            while (STATION_STATE.stationIndex < STATION_STATE.queue.length) {
                if (STATION_STATE.stopped) break;

                await waitIfStationNamingPaused();
                if (STATION_STATE.stopped) break;

                const station = STATION_STATE.queue[STATION_STATE.stationIndex];
                const displayPosition = STATION_STATE.stationIndex + 1;

                setStationUiValue('progress', `${displayPosition} / ${STATION_STATE.queue.length}`);
                setStationUiValue('current', station.displayName);
                setStationUiValue('address', 'Opening station...');
                setStationUiValue('town', 'Waiting...');
                setStationUiValue('before', station.displayName);
                setStationUiValue('after', 'Waiting...');
                setStationUiValue('status', 'Opening station');

                stationLog(`Station ${displayPosition}/${STATION_STATE.queue.length}: ${station.displayName}`, 'station');
                stationLog(`Type: ${station.typeLabel} | building_type_id=${station.buildingTypeId ?? 'unknown'} | suffix=${station.suffix || 'none'}`, 'info');

                const result = await processOneStationName(station);

                if (result === 'renamed') {
                    STATION_STATE.renamedCount++;
                } else if (result === 'previewed') {
                    STATION_STATE.previewedCount++;
                } else {
                    STATION_STATE.skippedCount++;
                }

                updateStationCounters();
                STATION_STATE.stationIndex++;

                if (!STATION_STATE.stopped) await sleep(350);
            }
        } finally {
            await closeStationNamingModal();
            STATION_STATE.activeIframe = null;
            STATION_STATE.running = false;
            STATION_STATE.paused = false;
            document.querySelector('#mc-station-pause').textContent = 'Pause';

            if (STATION_STATE.stopped) {
                setStationUiValue('status', 'Stopped');
                stationLog(`Stopped. Renamed ${STATION_STATE.renamedCount}, previewed ${STATION_STATE.previewedCount}, skipped ${STATION_STATE.skippedCount}.`, 'error');
            } else {
                setStationUiValue('status', 'Finished');
                setStationUiValue('progress', `${STATION_STATE.queue.length} / ${STATION_STATE.queue.length}`);
                stationLog(`Finished. Renamed ${STATION_STATE.renamedCount}, previewed ${STATION_STATE.previewedCount}, skipped ${STATION_STATE.skippedCount}.`, 'done');
            }
        }
    }

    async function processOneStationName(station) {
        if (!station.suffix) {
            stationLog(`Skipped: no safe naming rule exists for building_type_id=${station.buildingTypeId ?? 'unknown'}.`, 'error');
            return 'skipped';
        }

        const stationEntry = findStationOverviewEntry(station.href);
        const stationLink = stationEntry?.link || null;
        if (!stationLink) {
            stationLog(`Skipped: station link no longer exists for ${station.href}.`, 'error');
            return 'skipped';
        }

        let iframe = null;

        try {
            iframe = await openStationWorkflowIframe(
                stationEntry,
                'station-naming',
                waitForStationNamingIframe
            );
            STATION_STATE.activeIframe = iframe;

            if (!iframe) throw new Error('Station lightbox iframe did not open.');

            let doc = await waitForStationNamingDocument(
                iframe,
                currentDoc => currentDoc.querySelector(`a[href="${station.href}/edit"]`),
                'normal station page'
            );

            if (!doc) throw new Error('Normal station page did not finish loading.');
            if (STATION_STATE.stopped) return 'skipped';

            await waitIfStationNamingPaused();
            setStationUiValue('status', 'Reading station address');

            // Do not depend on clicking Move building. MissionChief can block that page
            // while vehicles are away. First try a read-only background request; when
            // that is unavailable, use the station coordinates and MissionChief's own
            // /reverse_address endpoint. The Move form is never submitted.
            const addressResult = await resolveStationAddress(station, doc);
            const address = String(addressResult.address || '').trim();

            if (!address) {
                throw new Error(addressResult.error || 'Station address could not be read from the Move page or coordinate fallback.');
            }

            setStationUiValue('address', address);
            stationLog(`Address: ${address}`, 'info');
            stationLog(`Address source: ${addressResult.source}`, 'debug');

            const parsed = extractStationArea(address);
            if (!parsed.postcode) throw new Error('No UK postcode could be extracted from the address.');
            if (!parsed.area) throw new Error(`No local area was found after postcode ${parsed.postcode}.`);

            const formattedArea = formatStationArea(parsed.area);
            if (!formattedArea) throw new Error('The detected local area became empty after formatting.');

            setStationUiValue('town', formattedArea);
            stationLog(`Postcode: ${parsed.postcode}`, 'info');
            stationLog(`Detected area: ${formattedArea}`, 'after');

            let proposedName = buildStationName(formattedArea, station.suffix, station.displayName);
            setStationUiValue('after', proposedName);
            stationLog(`BEFORE: ${station.displayName}`, 'before');
            stationLog(`AFTER : ${proposedName}`, 'after');

            if (STATION_STATE.action !== 'save') {
                setStationUiValue('status', 'Preview complete');
                stationLog('Preview only: nothing was saved.', 'info');
                return 'previewed';
            }

            if (STATION_STATE.stopped) return 'skipped';
            await waitIfStationNamingPaused();

            // The iframe is still on the normal station page because address reading
            // now happens in the background. Open Edit directly from this page.
            if (STATION_STATE.stopped) return 'skipped';

            setStationUiValue('status', 'Opening Edit');
            const editLink = doc.querySelector(`a[href="${station.href}/edit"]`);
            if (!editLink) throw new Error('Edit button was not found.');

            stationDebug(`Clicking Edit: ${editLink.getAttribute('href')}`);
            editLink.click();

            doc = await waitForStationNamingDocument(
                iframe,
                currentDoc => currentDoc.querySelector('#building_name')
                    && currentDoc.querySelector(`form[action="${station.href}"] input[name="_method"][value="patch"]`),
                'Edit station page'
            );

            if (!doc) throw new Error('Edit station page or #building_name did not load.');

            const nameInput = doc.querySelector('#building_name');
            const saveButton = doc.querySelector('input.btn-success[type="submit"][value="Save"], button.btn-success[type="submit"]');
            if (!nameInput || !saveButton) throw new Error('Station name field or Save button was not found.');

            const actualBefore = String(nameInput.value || '').trim();
            proposedName = buildStationName(formattedArea, station.suffix, actualBefore);
            setStationUiValue('before', actualBefore || station.displayName);
            setStationUiValue('after', proposedName);

            if (actualBefore === proposedName) {
                stationLog(`Already correct: ${proposedName}`, 'info');
                setStationUiValue('status', 'Already correct');
                return 'skipped';
            }

            if (STATION_STATE.stopped) return 'skipped';
            await waitIfStationNamingPaused();

            nameInput.focus();
            nameInput.value = proposedName;
            nameInput.dispatchEvent(new Event('input', { bubbles: true }));
            nameInput.dispatchEvent(new Event('change', { bubbles: true }));

            stationLog(`EDIT BEFORE: ${actualBefore}`, 'before');
            stationLog(`EDIT AFTER : ${proposedName}`, 'after');
            setStationUiValue('status', 'Saving station');

            saveButton.click();

            const saved = await verifyStationNameSaved(station.href, proposedName);
            if (!saved) throw new Error('Save could not be verified. The script did not count this station as renamed.');

            station.displayName = proposedName;
            updateStationListName(station.href, proposedName);
            setStationUiValue('status', 'Saved');
            stationLog(`Saved and verified: ${proposedName}`, 'done');
            return 'renamed';
        } catch (error) {
            stationLog(`Skipped ${station.displayName}: ${error?.message || error}`, 'error');
            stationDebug(error?.stack || String(error));
            return 'skipped';
        } finally {
            await closeStationNamingModal();
            STATION_STATE.activeIframe = null;
        }
    }

    async function resolveStationAddress(station, stationDoc) {
        const movePageResult = await fetchStationMoveAddress(station);
        if (movePageResult.address) return movePageResult;

        stationDebug(`Move-page address unavailable for ${station.displayName}: ${movePageResult.error || 'no #building_address returned'}`);

        const coordinates = await getStationCoordinates(station, stationDoc);
        if (!coordinates) {
            return {
                address: '',
                source: 'none',
                error: 'Move building is unavailable and no station coordinates could be found for the address fallback.'
            };
        }

        stationDebug(`Coordinate fallback: ${coordinates.latitude}, ${coordinates.longitude} (${coordinates.source})`);

        const reverseResult = await fetchMissionChiefReverseAddress(coordinates.latitude, coordinates.longitude);
        if (!reverseResult.address) {
            return {
                address: '',
                source: coordinates.source,
                error: reverseResult.error || 'MissionChief reverse-address lookup returned no address.'
            };
        }

        return {
            address: reverseResult.address,
            source: `MissionChief reverse address via ${coordinates.source}`,
            latitude: coordinates.latitude,
            longitude: coordinates.longitude
        };
    }

    async function fetchStationMoveAddress(station) {
        const url = `${station.href}/move`;

        try {
            const response = await stationFetchWithTimeout(url, {
                credentials: 'same-origin',
                cache: 'no-store'
            }, 9000);

            if (!response.ok) {
                return {
                    address: '',
                    source: 'Move building page',
                    error: `Move building request returned HTTP ${response.status}.`
                };
            }

            const html = await response.text();
            const doc = new DOMParser().parseFromString(html, 'text/html');
            const address = String(doc.querySelector('#building_address')?.value || '').trim();

            if (address) {
                return {
                    address,
                    source: 'Move building page (background read only)'
                };
            }

            const pageMessage = cleanText(
                doc.querySelector('.alert-danger, .alert-warning, #infoBox, .toast-message')?.textContent || ''
            );
            const responsePath = (() => {
                try {
                    return new URL(response.url, location.origin).pathname;
                } catch (_error) {
                    return response.url || url;
                }
            })();

            return {
                address: '',
                source: 'Move building page',
                error: pageMessage
                    ? `${pageMessage} (response path: ${responsePath})`
                    : `No #building_address was returned (response path: ${responsePath}).`
            };
        } catch (error) {
            return {
                address: '',
                source: 'Move building page',
                error: `Move building request failed: ${error?.message || error}`
            };
        }
    }

    async function getStationCoordinates(station, stationDoc) {
        const fromPageCache = findBuildingCoordinatesInPageCaches(station.buildingId);
        if (fromPageCache) return { ...fromPageCache, source: 'MissionChief building marker cache' };

        const fromDocument = extractCoordinatesFromStationDocument(stationDoc);
        if (fromDocument) return { ...fromDocument, source: 'station page' };

        await loadMissionChiefBuildingCoordinates();
        const fromLoadedData = STATION_STATE.buildingCoordinateCache.get(String(station.buildingId));
        if (fromLoadedData) return { ...fromLoadedData, source: 'MissionChief buildings data' };

        return null;
    }

    function extractCoordinatesFromStationDocument(doc) {
        if (!doc) return null;

        const latitudeInput = doc.querySelector('#building_latitude, input[name="building[latitude]"]');
        const longitudeInput = doc.querySelector('#building_longitude, input[name="building[longitude]"]');
        const direct = normalizeCoordinates(latitudeInput?.value, longitudeInput?.value);
        if (direct) return direct;

        const dataElement = doc.querySelector('[data-latitude][data-longitude], [data-lat][data-lng]');
        if (dataElement) {
            const dataCoordinates = normalizeCoordinates(
                dataElement.getAttribute('data-latitude') ?? dataElement.getAttribute('data-lat'),
                dataElement.getAttribute('data-longitude') ?? dataElement.getAttribute('data-lng')
            );
            if (dataCoordinates) return dataCoordinates;
        }

        const patterns = [
            /(?:setView|L\.marker)\s*\(\s*\[\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\]/i,
            /latitude\s*[:=]\s*["']?(-?\d+(?:\.\d+)?)["']?[\s\S]{0,160}?longitude\s*[:=]\s*["']?(-?\d+(?:\.\d+)?)/i
        ];

        for (const script of doc.scripts) {
            const scriptText = script.textContent || '';
            if (!scriptText) continue;

            for (const pattern of patterns) {
                const match = scriptText.match(pattern);
                const parsed = normalizeCoordinates(match?.[1], match?.[2]);
                if (parsed) return parsed;
            }
        }

        return null;
    }

    function findBuildingCoordinatesInPageCaches(buildingId) {
        const id = String(buildingId || '');
        const cacheCandidates = [];

        try {
            cacheCandidates.push(window.building_markers_params_cache_per_id);
        } catch (_error) {}

        try {
            if (window.parent && window.parent !== window) {
                cacheCandidates.push(window.parent.building_markers_params_cache_per_id);
            }
        } catch (_error) {}

        for (const cache of cacheCandidates) {
            const building = getBuildingRecordFromCache(cache, id);
            const coordinates = normalizeCoordinates(building?.latitude, building?.longitude);
            if (coordinates) {
                STATION_STATE.buildingCoordinateCache.set(id, coordinates);
                return coordinates;
            }
        }

        return STATION_STATE.buildingCoordinateCache.get(id) || null;
    }

    function getBuildingRecordFromCache(cache, buildingId) {
        if (!cache) return null;

        const numericId = Number(buildingId);
        const keys = [buildingId, Number.isFinite(numericId) ? numericId : buildingId];

        if (typeof cache.get === 'function') {
            for (const key of keys) {
                const value = cache.get(key);
                if (value) return value;
            }
        }

        if (Array.isArray(cache)) {
            return cache.find(item => String(item?.id ?? item?.building_id ?? '') === String(buildingId)) || null;
        }

        if (typeof cache === 'object') {
            for (const key of keys) {
                if (cache[key]) return cache[key];
            }

            return Object.values(cache).find(item => String(item?.id ?? item?.building_id ?? '') === String(buildingId)) || null;
        }

        return null;
    }

    async function loadMissionChiefBuildingCoordinates() {
        if (STATION_STATE.buildingDataPromise) {
            await STATION_STATE.buildingDataPromise;
            return;
        }

        STATION_STATE.buildingDataPromise = (async () => {
            try {
                const response = await stationFetchWithTimeout('/building/buildings_json', {
                    credentials: 'same-origin',
                    cache: 'no-store'
                }, 15000);

                if (!response.ok) {
                    stationDebug(`Buildings-data fallback returned HTTP ${response.status}.`);
                    return;
                }

                const payload = await response.json();
                const records = extractBuildingRecords(payload);
                const wantedIds = new Set(
                    STATION_STATE.stations
                        .map(station => String(station?.buildingId || ''))
                        .filter(Boolean)
                );
                const restrictToVisibleStations = wantedIds.size > 0;

                records.forEach(building => {
                    const id = String(building?.id ?? building?.building_id ?? '');
                    if (!id || (restrictToVisibleStations && !wantedIds.has(id))) return;

                    const coordinates = normalizeCoordinates(building?.latitude, building?.longitude);
                    if (coordinates) STATION_STATE.buildingCoordinateCache.set(id, coordinates);
                });

                stationDebug(`Buildings-data fallback cached ${STATION_STATE.buildingCoordinateCache.size} in-scope coordinate record(s).`);
            } catch (error) {
                stationDebug(`Buildings-data fallback failed: ${error?.message || error}`);
            }
        })();

        await STATION_STATE.buildingDataPromise;
    }

    function extractBuildingRecords(payload) {
        if (!payload) return [];
        if (Array.isArray(payload)) return payload;
        if (Array.isArray(payload.buildings)) return payload.buildings;
        if (Array.isArray(payload.result)) return payload.result;
        if (Array.isArray(payload.data)) return payload.data;

        if (typeof payload === 'object') {
            const values = Object.values(payload);
            const directRecords = values.filter(value => value && typeof value === 'object' && !Array.isArray(value));
            if (directRecords.some(value => 'latitude' in value && 'longitude' in value)) return directRecords;

            for (const value of values) {
                if (Array.isArray(value)) return value;
                if (value && typeof value === 'object') {
                    const nested = extractBuildingRecords(value);
                    if (nested.length) return nested;
                }
            }
        }

        return [];
    }

    async function fetchMissionChiefReverseAddress(latitude, longitude) {
        const coordinates = normalizeCoordinates(latitude, longitude);
        if (!coordinates) {
            return { address: '', error: 'Invalid coordinates were supplied to the reverse-address lookup.' };
        }

        const query = new URLSearchParams({
            latitude: String(coordinates.latitude),
            longitude: String(coordinates.longitude)
        });

        try {
            const response = await stationFetchWithTimeout(`/reverse_address?${query.toString()}`, {
                credentials: 'same-origin',
                cache: 'no-store',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest'
                }
            }, 10000);

            if (!response.ok) {
                return { address: '', error: `Reverse-address lookup returned HTTP ${response.status}.` };
            }

            let address = String(await response.text()).trim();
            if (/^<!doctype|^<html/i.test(address)) {
                return { address: '', error: 'Reverse-address lookup returned an HTML page instead of an address.' };
            }

            if ((address.startsWith('"') && address.endsWith('"')) || (address.startsWith("'") && address.endsWith("'"))) {
                try {
                    address = JSON.parse(address);
                } catch (_error) {
                    address = address.slice(1, -1);
                }
            }

            address = String(address || '').replace(/<[^>]+>/g, ' ').replace(/\s+/g, ' ').trim();
            if (!address) {
                return { address: '', error: 'Reverse-address lookup returned an empty or invalid response.' };
            }

            return { address };
        } catch (error) {
            return { address: '', error: `Reverse-address lookup failed: ${error?.message || error}` };
        }
    }

    function normalizeCoordinates(latitude, longitude) {
        const lat = Number(latitude);
        const lng = Number(longitude);

        if (!Number.isFinite(lat) || !Number.isFinite(lng)) return null;
        if (lat < -90 || lat > 90 || lng < -180 || lng > 180) return null;

        return { latitude: lat, longitude: lng };
    }

    async function stationFetchWithTimeout(url, options = {}, timeoutMs = 10000) {
        const controller = new AbortController();
        STATION_STATE.activeControllers.add(controller);
        const timer = setTimeout(() => controller.abort(), timeoutMs);

        try {
            return await fetch(url, {
                ...options,
                signal: controller.signal
            });
        } finally {
            clearTimeout(timer);
            STATION_STATE.activeControllers.delete(controller);
        }
    }

    function extractStationArea(address) {
        const input = String(address || '').trim();
        const postcodeRegex = /\b(GIR\s?0AA|(?:[A-PR-UWYZ][0-9][0-9A-HJKPSTUW]?|[A-PR-UWYZ][A-HK-Y][0-9][0-9ABEHMNPRV-Y]?)\s?[0-9][ABD-HJLNP-UW-Z]{2})\b/i;
        const match = input.match(postcodeRegex);

        if (!match || match.index == null) {
            return { postcode: '', afterPostcode: '', area: '' };
        }

        const postcode = match[1].toUpperCase().replace(/\s+/g, ' ').trim();
        const afterPostcode = input
            .slice(match.index + match[0].length)
            .replace(/^[\s,;:\-]+/, '')
            .trim();

        const parts = afterPostcode
            .split(',')
            .map(part => part.trim())
            .filter(Boolean);

        const countryOnly = /^(UNITED KINGDOM|UK|SCOTLAND|ENGLAND|WALES|NORTHERN IRELAND)$/i;
        while (parts.length > 1 && countryOnly.test(parts[parts.length - 1])) parts.pop();

        return {
            postcode,
            afterPostcode,
            area: parts.at(-1) || afterPostcode
        };
    }

    function formatStationArea(area) {
        return String(area || '')
            .replace(/\band\b/gi, '&')
            .replace(/\s*&\s*/g, ' & ')
            .replace(/^[\s,;:\-]+|[\s,;:\-]+$/g, '')
            .replace(/\s+/g, ' ')
            .trim()
            .toUpperCase();
    }

    function buildStationName(formattedArea, suffix, currentName) {
        const sequence = getExistingStationSequence(currentName, suffix);
        return `${formattedArea}${suffix}${sequence}`;
    }

    function getExistingStationSequence(currentName, suffix) {
        if (!suffix) return '';
        const escapedSuffix = suffix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        const match = String(currentName || '').trim().match(new RegExp(`${escapedSuffix}\\s*(\\d+)$`, 'i'));
        return match ? match[1] : '';
    }

    function getBuildingIdFromHref(href) {
        const match = String(href || '').match(/\/buildings\/(\d+)/);
        return match ? match[1] : '';
    }

    async function waitForStationNamingIframe(stationHref, preferredIframe = null, maximumAttempts = 80) {
        for (let i = 0; i < maximumAttempts; i++) {
            if (STATION_STATE.stopped) return null;

            const candidates = [
                preferredIframe,
                ...document.querySelectorAll(
                    'iframe.lightbox_iframe[src^="/buildings/"], ' +
                    'iframe#lssmv4-redesign-lightbox-iframe, ' +
                    'iframe.mc-namer-managed-station-iframe'
                )
            ].filter(Boolean);

            for (const iframe of candidates.reverse()) {
                try {
                    const doc = iframe.contentDocument;
                    const currentPath = iframe.contentWindow?.location?.pathname || iframe.getAttribute('src') || '';
                    if (doc && (currentPath.startsWith(stationHref) || doc.querySelector(`a[href="${stationHref}/move"], form[action="${stationHref}"], form[action="${stationHref}/move_do"]`))) {
                        return iframe;
                    }
                } catch (error) {
                    stationDebug(`Iframe access retry: ${error?.message || error}`);
                }
            }

            await sleep(250);
        }

        return null;
    }

    async function waitForStationNamingDocument(iframe, predicate, label) {
        for (let i = 0; i < 100; i++) {
            if (STATION_STATE.stopped) return null;

            try {
                const doc = iframe?.contentDocument;
                if (doc && doc.readyState !== 'loading' && predicate(doc)) {
                    stationDebug(`${label} ready at ${iframe.contentWindow?.location?.pathname || iframe.getAttribute('src') || 'unknown path'}`);
                    return doc;
                }
            } catch (error) {
                stationDebug(`${label} wait retry: ${error?.message || error}`);
            }

            await sleep(200);
        }

        return null;
    }

    async function verifyStationNameSaved(stationHref, expectedName) {
        for (let attempt = 1; attempt <= 14; attempt++) {
            if (STATION_STATE.stopped) return false;

            await sleep(attempt === 1 ? 500 : 350);

            try {
                const response = await stationFetchWithTimeout(`${stationHref}/edit`, {
                    credentials: 'same-origin',
                    cache: 'no-store'
                }, 10000);

                if (!response.ok) {
                    stationDebug(`Save verification HTTP ${response.status}, attempt ${attempt}.`);
                    continue;
                }

                const html = await response.text();
                const doc = new DOMParser().parseFromString(html, 'text/html');
                const savedName = String(doc.querySelector('#building_name')?.value || '').trim();
                stationDebug(`Save verification attempt ${attempt}: "${savedName}"`);

                if (savedName === expectedName) return true;
            } catch (error) {
                stationDebug(`Save verification attempt ${attempt} failed: ${error?.message || error}`);
            }
        }

        return false;
    }

    function updateStationListName(href, newName) {
        const entry = findStationOverviewEntry(href);
        const link = entry?.link;
        const container = entry?.container || getStationOverviewContainer(link);
        if (!link) return;

        const sameBuildingLinks = container
            ? [...container.querySelectorAll('a[href]')]
                .filter(candidate => normaliseStationOverviewHref(candidate.getAttribute('href')) === entry.href)
            : [link];
        const nameLink = sameBuildingLinks.find(candidate => {
            const label = cleanText(candidate.textContent);
            return label && !isGenericStationActionText(label);
        });
        const nameNode = nameLink || container?.querySelector(
            '[data-building-name], .building_list_title, .building-list-title, ' +
            '.building_name, .building-name, .panel-heading, .card-title'
        );

        if (nameNode) {
            nameNode.textContent = newName;
            nameNode.setAttribute?.('data-building-name', newName);
        }
        if (container) container.setAttribute('search_attribute', newName);
    }

    async function closeStationNamingModal(iframe = STATION_STATE.activeIframe) {
        if (removeManagedStationIframe(iframe)) {
            if (STATION_STATE.activeIframe === iframe) STATION_STATE.activeIframe = null;
            await sleep(50);
            return;
        }

        const closeButtons = [...document.querySelectorAll('span.lightbox-close')];
        const closeButton = closeButtons.reverse().find(button => button.offsetParent !== null) || closeButtons[0];

        if (closeButton) {
            closeButton.click();
            await sleep(450);
        }
    }

    async function waitIfStationNamingPaused() {
        while (STATION_STATE.paused && !STATION_STATE.stopped) {
            await sleep(250);
        }
    }

    function updateStationCounters() {
        setStationUiValue('renamed', STATION_STATE.renamedCount);
        setStationUiValue('skipped', STATION_STATE.skippedCount);
    }

    function toggleStationDebug() {
        STATION_STATE.debug = !STATION_STATE.debug;
        document.querySelector('#mc-station-debug').textContent = STATION_STATE.debug ? 'Debug: ON' : 'Debug: OFF';
        stationLog(`Debug ${STATION_STATE.debug ? 'enabled' : 'disabled'}.`, 'debug');
    }

    function clearStationLog() {
        clearBoundedToolLog(getToolElementById('mc-station-log'));
    }

    function setStationUiValue(field, value) {
        const map = {
            status: 'mc-station-status',
            current: 'mc-station-current',
            address: 'mc-station-address',
            town: 'mc-station-town',
            before: 'mc-station-before',
            after: 'mc-station-after',
            progress: 'mc-station-progress',
            renamed: 'mc-station-renamed',
            skipped: 'mc-station-skipped'
        };

        const el = getToolElementById(map[field]);
        if (el) el.textContent = String(value);
    }

    function stationLog(message, type = 'info') {
        const logBox = getToolElementById('mc-station-log');
        if (!logBox) return;

        const line = document.createElement('div');
        line.className = `mc-log-${type}`;
        line.textContent = message;
        appendBoundedToolLog(logBox, line);
    }

    function stationDebug(message) {
        if (!STATION_STATE.debug) return;
        stationLog(`[DEBUG] ${message}`, 'debug');
    }


    function getPersonnelProfileStationTypes() {
        const profile = getPersonnelProfileDefinition();
        return Array.isArray(profile?.stationTypes) ? profile.stationTypes.map(String) : [];
    }

    function getPersonnelStationScopeLabel() {
        const service = getPersonnelServiceDefinition();
        const stationTypes = getPersonnelProfileStationTypes();

        if (service === PERSONNEL_SERVICE_DEFINITIONS.medical) return 'ambulance stations';
        if (stationTypes.length === 1 && stationTypes[0] === 'AIR') return 'police aviation stations';
        if (stationTypes.length === 1 && stationTypes[0] === 'EOD') return 'EOD / bomb disposal stations';
        if (service === PERSONNEL_SERVICE_DEFINITIONS.police) return 'relevant Police stations';
        return `relevant ${service.label} stations`;
    }

    function refreshPersonnelStations() {
        if (!isLivePersonnelProfile()) {
            const service = getPersonnelServiceDefinition();
            const profile = getPersonnelProfileDefinition();
            personnelLog(`${service.label} > ${profile.label} is currently a UI preview only. No station scan was started.`, 'error');
            setPersonnelUiValue('status', 'Profile UI preview');
            return;
        }

        if (STATE.running || STATION_STATE.running) {
            personnelLog('A naming tool is currently running. Stop it before refreshing Personnel Assignment.', 'error');
            setPersonnelUiValue('status', 'Blocked by naming tool');
            return;
        }

        if (PERSONNEL_STATE.running) {
            personnelLog('Stop Personnel Assignment before refreshing the station list.', 'error');
            return;
        }

        const allowedStationTypes = new Set(getPersonnelProfileStationTypes());
        const scopeLabel = getPersonnelStationScopeLabel();
        setPersonnelUiValue('status', `Refreshing ${scopeLabel}...`);
        personnelLog(`Refreshing ${scopeLabel}...`, 'info');

        const stationEntries = getStationOverviewEntries();

        PERSONNEL_STATION_LINK_BY_HREF.clear();
        stationEntries.forEach(entry => {
            if (entry.href) PERSONNEL_STATION_LINK_BY_HREF.set(entry.href, entry.link);
        });

        PERSONNEL_STATE.stations = stationEntries
            .map((entry, index) => ({
                index,
                href: entry.href,
                buildingId: entry.buildingId,
                displayName: entry.displayName,
                buildingTypeId: entry.buildingTypeId,
                stationType:
                    STATION_BUILDING_TYPE_INFO[entry.buildingTypeId]?.stationType ||
                    detectStationType(entry.displayName)
            }))
            .filter(station => station.href && station.buildingId && allowedStationTypes.has(station.stationType));

        PERSONNEL_STATE.filteredStations = [...PERSONNEL_STATE.stations];
        populatePersonnelStartDropdown();
        setPersonnelUiValue('status', 'Ready');

        personnelLog(`${scopeLabel.replace(/^./, value => value.toUpperCase())} found: ${PERSONNEL_STATE.filteredStations.length}`, 'info');
        if (PERSONNEL_STATE.filteredStations.length) {
            personnelLog(`First: ${PERSONNEL_STATE.filteredStations[0].displayName}`, 'info');
            personnelLog(`Last : ${PERSONNEL_STATE.filteredStations[PERSONNEL_STATE.filteredStations.length - 1].displayName}`, 'info');
        }
    }

    function populatePersonnelStartDropdown() {
        const select = getToolElementById('mc-personnel-startfrom');
        if (!select) return;

        select.replaceChildren();
        PERSONNEL_START_OPTION_BY_HREF.clear();

        if (!PERSONNEL_STATE.filteredStations.length) {
            const option = document.createElement('option');
            option.value = '';
            option.textContent = `No ${getPersonnelStationScopeLabel()} found`;
            select.appendChild(option);
            PERSONNEL_STATE.selectedHref = '';
            setPersonnelUiValue('current', 'None');
            setPersonnelUiValue('progress', '0 / 0');
            return;
        }

        const fragment = document.createDocumentFragment();
        const firstOption = document.createElement('option');
        firstOption.value = PERSONNEL_STATE.filteredStations[0].href;
        firstOption.textContent = `Start from first ${getPersonnelStationScopeLabel().replace(/s$/, '')}`;
        firstOption.dataset.personnelStartOption = 'true';
        fragment.appendChild(firstOption);

        PERSONNEL_STATE.filteredStations.forEach(station => {
            const option = document.createElement('option');
            option.value = station.href;
            option.dataset.personnelStationOption = 'true';
            option.textContent = `${station.displayName} [building type ${station.buildingTypeId ?? '?'}]`;
            PERSONNEL_START_OPTION_BY_HREF.set(String(station.href), option);
            fragment.appendChild(option);
        });

        select.appendChild(fragment);
        PERSONNEL_STATE.selectedHref = select.value;
        setPersonnelUiValue('progress', `0 / ${PERSONNEL_STATE.filteredStations.length}`);
        updatePersonnelSelectionPreview();
    }

    function updatePersonnelSelectionPreview() {
        const selectedHref = document.querySelector('#mc-personnel-startfrom')?.value || '';
        const station = PERSONNEL_STATE.filteredStations.find(item => item.href === selectedHref);

        PERSONNEL_STATE.selectedHref = selectedHref;
        setPersonnelUiValue('current', station?.displayName || 'None');
        setPersonnelUiValue('vehicle', 'None');
        personnelDebug(`Selected station: ${station?.displayName || 'none'} | href=${selectedHref}`);
    }


    async function buildPersonnelTrainingRegisterOneClick() {
        if (STATE.running || STATION_STATE.running) {
            personnelLog(
                'A naming tool is currently running. Stop it before building the Personnel Register.',
                'error'
            );
            setPersonnelUiValue('status', 'Blocked by naming tool');
            return;
        }

        if (PERSONNEL_STATE.running) {
            personnelLog(
                'Personnel Assignment or a register build is already running.',
                'debug'
            );
            return;
        }

        const stations = getStationOverviewEntries()
            .map((entry, index) => ({
                index,
                href: entry.href,
                buildingId: entry.buildingId,
                displayName: entry.displayName,
                buildingTypeId: entry.buildingTypeId,
                stationType:
                    STATION_BUILDING_TYPE_INFO[entry.buildingTypeId]?.stationType ||
                    detectStationType(entry.displayName)
            }))
            .filter(station => station.href && station.buildingId);

        if (!stations.length) {
            personnelLog(
                'No stations were found on the current station overview.',
                'error'
            );
            setPersonnelUiValue('status', 'No stations found');
            return;
        }

        const button = document.querySelector('#mc-personnel-build-register');
        const previousAction = PERSONNEL_STATE.action;

        PERSONNEL_STATE.running = true;
        PERSONNEL_STATE.registerBuilding = true;
        PERSONNEL_STATE.paused = false;
        PERSONNEL_STATE.stopped = false;
        PERSONNEL_STATE.action = 'preview';
        PERSONNEL_STATE.activeController = null;
        PERSONNEL_STATE.lastRequestAt = 0;

        if (button) {
            button.disabled = true;
            button.textContent = 'Building Register...';
        }

        document.querySelector('#mc-personnel-pause').textContent = 'Pause';
        setPersonnelUiValue('status', 'Building all-station personnel register');
        setPersonnelUiValue('progress', `0 / ${stations.length}`);
        setPersonnelUiValue('vehicle', 'None');

        personnelLog(
            `One-click register build started for all ${stations.length} station(s). Every discovered vehicle is read from its own assignment page. No personnel assignments will be changed.`,
            'info'
        );

        let completedStations = 0;
        let scannedVehicles = 0;
        let exactVehiclePagesRead = 0;
        let skippedStations = 0;
        let failedStations = 0;
        let failedVehicles = 0;

        try {
            for (let stationIndex = 0; stationIndex < stations.length; stationIndex++) {
                if (PERSONNEL_STATE.stopped) break;
                await waitIfPersonnelPaused();
                if (PERSONNEL_STATE.stopped) break;

                const station = stations[stationIndex];
                setPersonnelUiValue('progress', `${stationIndex + 1} / ${stations.length}`);
                setPersonnelUiValue('current', station.displayName);
                setPersonnelUiValue('vehicle', 'Reading station vehicles');
                setPersonnelUiValue('status', 'Scanning station vehicle table');
                personnelLog(
                    `Register station ${stationIndex + 1}/${stations.length}: ${station.displayName}`,
                    'station'
                );

                try {
                    const stationPage = await personnelFetchDocument(station.href, 14000);
                    const vehicles = getPersonnelVehicleQueue(stationPage.doc, []);

                    if (!vehicles.length) {
                        skippedStations++;
                        personnelLog('No vehicles found at this station.', 'debug');
                        continue;
                    }

                    const mergedPersonnel = new Map();
                    const verifiedVehicles = [];

                    for (let vehicleIndex = 0; vehicleIndex < vehicles.length; vehicleIndex++) {
                        if (PERSONNEL_STATE.stopped) break;
                        await waitIfPersonnelPaused();
                        if (PERSONNEL_STATE.stopped) break;

                        const vehicle = vehicles[vehicleIndex];
                        setPersonnelUiValue(
                            'vehicle',
                            `${vehicle.name || vehicle.vehicleId} (${vehicleIndex + 1}/${vehicles.length})`
                        );
                        setPersonnelUiValue('status', 'Reading exact vehicle assignments');

                        try {
                            const assignmentPage = await personnelFetchDocument(
                                vehicle.assignmentHref,
                                14000
                            );

                            if (!assignmentPage.doc.querySelector('#personal_table')) {
                                throw new Error('Personnel table was not present on the assignment page.');
                            }

                            const assignment = parseVehicleAssignmentPage(
                                assignmentPage.doc,
                                vehicle.vehicleId
                            );

                            assignment.rows.forEach(person => {
                                const personnelId = String(person?.personnelId || '');
                                if (!personnelId) return;

                                const existing = mergedPersonnel.get(personnelId);
                                const newHasExactBinding = Boolean(person.assignedVehicleId);
                                const existingHasExactBinding = Boolean(existing?.assignedVehicleId);

                                if (
                                    !existing ||
                                    (person.assignedHere && !existing.assignedHere) ||
                                    (newHasExactBinding && !existingHasExactBinding)
                                ) {
                                    mergedPersonnel.set(personnelId, person);
                                }
                            });

                            verifiedVehicles.push(vehicle);
                            exactVehiclePagesRead++;
                        } catch (error) {
                            failedVehicles++;
                            personnelLog(
                                `Exact vehicle scan failed for ${vehicle.name || vehicle.vehicleId}: ${error?.message || error}`,
                                'error'
                            );
                        }
                    }

                    if (!verifiedVehicles.length) {
                        failedStations++;
                        personnelLog(
                            'No exact vehicle assignment page could be verified at this station.',
                            'error'
                        );
                        continue;
                    }

                    const published = publishPersonnelVehicleTrainingRegistry({
                        station,
                        vehicles: verifiedVehicles,
                        personnel: Array.from(mergedPersonnel.values()),
                        source: 'one-click-all-station-exact-register-scan',
                        pruneMissingVehicles: false
                    });

                    scannedVehicles += Number(published || 0);
                    completedStations++;
                    personnelLog(
                        `Register updated for ${published} exact vehicle(s); assigned training was read from ${verifiedVehicles.length} vehicle page(s).`,
                        'done'
                    );
                } catch (error) {
                    failedStations++;
                    personnelLog(
                        `Register scan failed at ${station.displayName}: ${error?.message || error}`,
                        'error'
                    );
                }
            }

            const saveResult = flushPersonnelTrainingRegistry(false);
            const stopped = PERSONNEL_STATE.stopped;
            const summary = [
                'PERSONNEL TRAINING REGISTER BUILD',
                '',
                `Status: ${stopped ? 'STOPPED' : 'COMPLETE'}`,
                `All station types considered: ${stations.length}`,
                `Stations scanned: ${completedStations}`,
                `Stations without vehicles: ${skippedStations}`,
                `Stations failed: ${failedStations}`,
                `Exact vehicle pages read: ${exactVehiclePagesRead}`,
                `Exact vehicles registered: ${scannedVehicles}`,
                `Vehicle pages failed: ${failedVehicles}`,
                `Registry retained: ${Number(saveResult?.retained || 0)}`,
                '',
                'Only personnel already assigned to each exact vehicle were recorded.',
                'No personnel assignments were changed.'
            ].join('\n');

            PERSONNEL_STATE.currentReport = summary;
            renderPersonnelReport(summary);
            setPersonnelUiValue('completed', completedStations);
            setPersonnelUiValue('vehicles', scannedVehicles);
            setPersonnelUiValue('assigned', 0);
            setPersonnelUiValue(
                'status',
                stopped ? 'Register build stopped' : 'All-station personnel register ready'
            );

            personnelLog(
                stopped
                    ? `Register build stopped after ${completedStations} station(s) and ${scannedVehicles} exact vehicle(s).`
                    : `Personnel register complete: ${completedStations} station(s), ${scannedVehicles} exact vehicle(s), no staffing changes.`,
                stopped ? 'error' : 'done'
            );
        } finally {
            flushPersonnelTrainingRegistry(true);
            PERSONNEL_STATE.running = false;
            PERSONNEL_STATE.registerBuilding = false;
            PERSONNEL_STATE.paused = false;
            PERSONNEL_STATE.action = previousAction;
            PERSONNEL_STATE.activeController = null;

            if (button) {
                button.disabled = false;
                button.textContent = 'Build Personnel Register';
            }

            document.querySelector('#mc-personnel-pause').textContent = 'Pause';
        }
    }

    function startPersonnelRun() {
        if (!isLivePersonnelProfile()) {
            const service = getPersonnelServiceDefinition();
            const profile = getPersonnelProfileDefinition();
            personnelLog(`${service.label} > ${profile.label} is shown for UI review only. Assignment has been safely blocked until that profile is implemented and tested.`, 'error');
            setPersonnelUiValue('status', 'Profile UI preview');
            return;
        }

        if (STATE.running || STATION_STATE.running) {
            personnelLog('A naming tool is currently running. Stop it before starting Personnel Assignment.', 'error');
            setPersonnelUiValue('status', 'Blocked by naming tool');
            return;
        }

        if (PERSONNEL_STATE.running) {
            personnelLog('Personnel Assignment is already running.', 'debug');
            return;
        }

        if (!PERSONNEL_STATE.filteredStations.length) {
            personnelLog(`No ${getPersonnelStationScopeLabel()} loaded. Press Refresh Stations first.`, 'error');
            setPersonnelUiValue('status', 'Refresh required');
            return;
        }

        const selectedHref = document.querySelector('#mc-personnel-startfrom')?.value || '';
        const startIndex = PERSONNEL_STATE.filteredStations.findIndex(station => station.href === selectedHref);

        if (startIndex < 0) {
            personnelLog(`Selected start station not found: ${selectedHref || 'none'}`, 'error');
            setPersonnelUiValue('status', 'Invalid start station');
            return;
        }

        PERSONNEL_STATE.mode =
            document.querySelector(
                '#mc-personnel-mode'
            )?.value ||
            'all';

        PERSONNEL_STATE.action =
            document.querySelector(
                '#mc-personnel-action'
            )?.value ||
            'preview';

        const unitsInput =
            document.querySelector(
                '#mc-personnel-units-required'
            );

        if (
            PERSONNEL_STATE.mode ===
            'target'
        ) {
            const configuredTarget =
                normalisePersonnelUnitsRequired(
                    unitsInput?.value ||
                    PERSONNEL_STATE
                        .configuredUnitsRequired ||
                    0
                );

            if (
                configuredTarget <=
                0
            ) {
                personnelLog(
                    'Target-units mode requires a Units required value greater than 0.',
                    'error'
                );

                setPersonnelUiValue(
                    'status',
                    'Enter a units target'
                );

                unitsInput?.focus();
                return;
            }

            PERSONNEL_STATE
                .configuredUnitsRequired =
                    configuredTarget;

            PERSONNEL_STATE.unitsRequired =
                configuredTarget;

            if (unitsInput) {
                unitsInput.value =
                    String(configuredTarget);
            }

            try {
                localStorage.setItem(
                    PERSONNEL_UNITS_REQUIRED_STORAGE_KEY,
                    String(configuredTarget)
                );
            } catch (_error) {}
        } else {
            // All Stations and Selected Station modes always process their
            // complete station scope. A saved target cannot stop them.
            PERSONNEL_STATE.unitsRequired =
                0;

            if (unitsInput) {
                unitsInput.value =
                    '0';
            }
        }

        PERSONNEL_STATE.queue = PERSONNEL_STATE.mode === 'single'
            ? [PERSONNEL_STATE.filteredStations[startIndex]]
            : PERSONNEL_STATE.filteredStations.slice(startIndex);
        PERSONNEL_STATE.running = true;
        PERSONNEL_STATE.paused = false;
        PERSONNEL_STATE.stopped = false;
        PERSONNEL_STATE.unitsFulfilled = 0;
        PERSONNEL_STATE.unitTargetReached = false;
        PERSONNEL_STATE.stationsTargetMet = 0;
        PERSONNEL_STATE.stationsTargetShort = 0;
        PERSONNEL_STATE.stationIndex = 0;
        PERSONNEL_STATE.completedStations = 0;
        PERSONNEL_STATE.skippedStations = 0;
        PERSONNEL_STATE.checkedVehicles = 0;
        PERSONNEL_STATE.plannedCount = 0;
        PERSONNEL_STATE.assignedCount = 0;
        PERSONNEL_STATE.trainingShortfall = 0;
        PERSONNEL_STATE.assignmentShortfall = 0;
        PERSONNEL_STATE.reports = [];
        PERSONNEL_STATE.currentReport = '';
        PERSONNEL_STATE.currentStationReport = '';
        PERSONNEL_STATE.lastStationReport = null;
        PERSONNEL_STATE.activeController = null;
        PERSONNEL_STATE.lastRequestAt = 0;
        PERSONNEL_SHORTFALL_CACHE = [];
        PERSONNEL_SHORTFALL_CACHE_SIZE = -1;

        document.querySelector('#mc-personnel-pause').textContent = 'Pause';
        updatePersonnelCounters();
        renderPersonnelAfterActionText('The latest completed station report will appear here.');
        renderPersonnelReport('Scanning has started. The completed overall report will appear here.');
        updatePersonnelTrainingShortfallHighlights();
        setPersonnelUiValue('progress', `0 / ${PERSONNEL_STATE.queue.length}`);
        setPersonnelUiValue('status', PERSONNEL_STATE.action === 'assign' ? 'Starting assignment run' : 'Starting preview');

        personnelLog(`Service/Profile: ${getPersonnelServiceDefinition().label} > ${getPersonnelProfileDefinition().label}`, 'info');
        personnelLog(
            `Mode: ${
                PERSONNEL_STATE.mode ===
                    'single'
                    ? 'Selected station only — scan the entire selected station'
                    : PERSONNEL_STATE.mode ===
                        'target'
                        ? `Ensure each ${getPersonnelStationScopeLabel().replace(/s$/, '')} has ${PERSONNEL_STATE.unitsRequired} fully staffed unit(s)`
                        : `All ${getPersonnelStationScopeLabel()} from selected start point — scan every station`
            }`,
            'info'
        );
        personnelLog(`Action: ${PERSONNEL_STATE.action === 'assign' ? 'ASSIGN AND VERIFY' : 'PREVIEW ONLY - no assignments will change'}`, PERSONNEL_STATE.action === 'assign' ? 'after' : 'info');
        personnelLog(
            PERSONNEL_STATE.mode ===
                'target'
                ? `Units required at every station: ${PERSONNEL_STATE.unitsRequired}. Existing fully covered units count first; only the station's remaining target will be planned or assigned before moving to the next station.`
                : PERSONNEL_STATE.mode ===
                    'single'
                    ? 'Units required: not used. Every matching unit at the selected station will be processed.'
                    : 'Units required: not used. Every relevant station and matching unit from the selected start point will be processed.',
            'info'
        );
        personnelLog(`Rule: ${getPersonnelProfileDefinition().requirement}.`, 'info');

        processPersonnelQueue().catch(error => {
            personnelLog(`Personnel Assignment stopped after an unexpected error: ${error?.message || error}`, 'error');
            personnelDebug(error?.stack || String(error));
            PERSONNEL_STATE.stopped = true;
            PERSONNEL_STATE.running = false;
            setPersonnelUiValue('status', 'Error');
        });
    }

    function togglePersonnelPause() {
        if (!PERSONNEL_STATE.running) {
            personnelLog('Nothing is currently running.', 'debug');
            return;
        }

        PERSONNEL_STATE.paused = !PERSONNEL_STATE.paused;
        document.querySelector('#mc-personnel-pause').textContent = PERSONNEL_STATE.paused ? 'Resume' : 'Pause';
        setPersonnelUiValue('status', PERSONNEL_STATE.paused ? 'Paused' : 'Running');
        personnelLog(PERSONNEL_STATE.paused ? 'Paused. The current safe request will finish before waiting.' : 'Resumed.', 'debug');
    }

    function stopPersonnelRun() {
        if (!PERSONNEL_STATE.running) {
            personnelLog('Nothing is currently running.', 'debug');
            return;
        }

        PERSONNEL_STATE.stopped = true;
        PERSONNEL_STATE.paused = false;
        document.querySelector('#mc-personnel-pause').textContent = 'Pause';
        setPersonnelUiValue('status', 'Stopping...');

        if (PERSONNEL_STATE.activeController) {
            try {
                PERSONNEL_STATE.activeController.abort();
            } catch (_error) {}
            PERSONNEL_STATE.activeController = null;
        }

        personnelLog('Stop requested. The active Personnel request was cancelled and no further work will run.', 'error');
    }

    async function processPersonnelQueue() {
        try {
            while (
                PERSONNEL_STATE.stationIndex <
                PERSONNEL_STATE.queue.length
            ) {
                if (PERSONNEL_STATE.stopped) break;

                await waitIfPersonnelPaused();
                if (PERSONNEL_STATE.stopped) break;

                const station =
                    PERSONNEL_STATE.queue[
                        PERSONNEL_STATE.stationIndex
                    ];

                const displayPosition =
                    PERSONNEL_STATE.stationIndex + 1;

                setPersonnelUiValue(
                    'progress',
                    `${displayPosition} / ${PERSONNEL_STATE.queue.length}`
                );
                setPersonnelUiValue(
                    'current',
                    station.displayName
                );
                setPersonnelUiValue(
                    'vehicle',
                    'None'
                );
                setPersonnelUiValue(
                    'status',
                    'Scanning station'
                );

                personnelLog(
                    `Station ${displayPosition}/${PERSONNEL_STATE.queue.length}: ${station.displayName}`,
                    'station'
                );

                let completedReport;

                try {
                    completedReport =
                        await processOnePersonnelStation(
                            station
                        );

                    if (isPersonnelPerStationTargetMode()) {
                        const stationTarget =
                            PERSONNEL_STATE.unitsRequired;

                        const stationFulfilled =
                            Math.min(
                                stationTarget,
                                Number(
                                    completedReport.fulfilledUnits
                                    || 0
                                )
                            );

                        completedReport.stationTarget =
                            stationTarget;
                        completedReport.stationTargetFulfilled =
                            stationFulfilled;
                        completedReport.stationTargetMet =
                            stationFulfilled >= stationTarget;
                        completedReport.stationTargetShortfallUnits =
                            Math.max(
                                0,
                                stationTarget - stationFulfilled
                            );

                        if (completedReport.stationTargetMet) {
                            PERSONNEL_STATE.stationsTargetMet++;
                        } else {
                            PERSONNEL_STATE.stationsTargetShort++;
                        }

                        PERSONNEL_STATE.unitsFulfilled +=
                            stationFulfilled;
                    } else {
                        PERSONNEL_STATE.unitsFulfilled +=
                            Number(
                                completedReport.fulfilledUnits
                                || 0
                            );
                    }

                    PERSONNEL_STATE.reports.push(
                        completedReport
                    );
                    PERSONNEL_STATE.completedStations++;
                    PERSONNEL_STATE.checkedVehicles +=
                        completedReport.vehiclesChecked;
                    PERSONNEL_STATE.plannedCount +=
                        completedReport.planned;
                    PERSONNEL_STATE.assignedCount +=
                        completedReport.assigned;
                    PERSONNEL_STATE.trainingShortfall +=
                        completedReport.trainingShortfall;
                    PERSONNEL_STATE.assignmentShortfall +=
                        completedReport.assignmentShortfall;

                    const targetText =
                        isPersonnelPerStationTargetMode()
                            ? (
                                completedReport.stationTargetMet
                                    ? ` | target PASSED ${completedReport.stationTargetFulfilled}/${completedReport.stationTarget}`
                                    : ` | target SHORT ${completedReport.stationTargetFulfilled}/${completedReport.stationTarget}`
                            )
                            : '';

                    personnelLog(
                        `${station.displayName}: vehicles=${completedReport.vehicleCount ?? completedReport.ambulances ?? 0}, units fulfilled=${Number(completedReport.fulfilledUnits || 0)}, qualified=${completedReport.trained}, need training=${completedReport.trainingShortfall}, unfilled=${completedReport.assignmentShortfall}${targetText}.`,
                        (
                            completedReport.trainingShortfall
                            || completedReport.assignmentShortfall
                            || (
                                isPersonnelPerStationTargetMode()
                                && !completedReport.stationTargetMet
                            )
                        )
                            ? 'error'
                            : 'done'
                    );
                } catch (error) {
                    if (
                        PERSONNEL_STATE.stopped
                        && error?.name === 'AbortError'
                    ) {
                        personnelLog(
                            'Active Personnel request cancelled.',
                            'debug'
                        );
                        break;
                    }

                    PERSONNEL_STATE.skippedStations++;

                    completedReport = {
                        stationName: station.displayName,
                        error: error?.message || String(error),
                        vehicleCount: 0,
                        ambulances: 0,
                        required: 0,
                        trained: 0,
                        availableAtScan: 0,
                        availableAtEnd: 0,
                        initialQualifiedFilled: 0,
                        finalQualifiedFilled: 0,
                        initialCriticalFilled: 0,
                        finalCriticalFilled: 0,
                        trainingShortfall: 0,
                        assignmentShortfall: 0,
                        planned: 0,
                        assigned: 0,
                        fulfilledUnits: 0,
                        vehiclesChecked: 0,
                        afterActionVerified: false,
                        verificationError:
                            error?.message || String(error),
                        vehicles: []
                    };

                    if (isPersonnelPerStationTargetMode()) {
                        completedReport.stationTarget =
                            PERSONNEL_STATE.unitsRequired;
                        completedReport.stationTargetFulfilled = 0;
                        completedReport.stationTargetMet = false;
                        completedReport.stationTargetShortfallUnits =
                            PERSONNEL_STATE.unitsRequired;
                        PERSONNEL_STATE.stationsTargetShort++;
                    }

                    PERSONNEL_STATE.reports.push(
                        completedReport
                    );

                    personnelLog(
                        `Skipped ${station.displayName}: ${error?.message || error}`,
                        'error'
                    );
                    personnelDebug(
                        error?.stack || String(error)
                    );
                }

                PERSONNEL_STATE.lastStationReport =
                    completedReport;

                flushPersonnelTrainingRegistry(true);

                renderPersonnelAfterAction(
                    completedReport
                );

                PERSONNEL_STATE.stationIndex++;
                updatePersonnelCounters();
                buildAndRenderPersonnelReport();

                if (PERSONNEL_STATE.mode === 'single') {
                    scrollPersonnelTo(
                        'mc-personnel-after-action-section'
                    );
                }

                if (!PERSONNEL_STATE.stopped) {
                    await waitPersonnelDelay(
                        PERSONNEL_STATION_GAP_MS
                    );
                }
            }
        } finally {
            PERSONNEL_STATE.running = false;
            PERSONNEL_STATE.paused = false;

            document.querySelector(
                '#mc-personnel-pause'
            ).textContent = 'Pause';

            buildAndRenderPersonnelReport();
            flushPersonnelTrainingRegistry(true);
            PERSONNEL_TRAINING_REGISTRY_CACHE = null;

            if (PERSONNEL_STATE.stopped) {
                setPersonnelUiValue(
                    'status',
                    'Stopped'
                );
                personnelLog(
                    'Stopped. The reports contain all stations completed before the stop request.',
                    'error'
                );
                return;
            }

            const targetMode =
                isPersonnelPerStationTargetMode();

            const hasTargetShortfall =
                targetMode
                && PERSONNEL_STATE.stationsTargetShort > 0;

            setPersonnelUiValue(
                'status',
                targetMode
                    ? (
                        hasTargetShortfall
                            ? 'Finished - some station targets not met'
                            : 'Finished - every station target met'
                    )
                    : 'Finished - report ready'
            );

            setPersonnelUiValue(
                'progress',
                `${PERSONNEL_STATE.queue.length} / ${PERSONNEL_STATE.queue.length}`
            );

            if (targetMode) {
                personnelLog(
                    `Finished. Target ${PERSONNEL_STATE.unitsRequired} per station: ${PERSONNEL_STATE.stationsTargetMet}/${PERSONNEL_STATE.completedStations} station(s) met; ${PERSONNEL_STATE.stationsTargetShort} short.`,
                    hasTargetShortfall
                        ? 'error'
                        : 'done'
                );
            }

            personnelLog(
                `Finished. Stations ${PERSONNEL_STATE.completedStations}, vehicles ${PERSONNEL_STATE.checkedVehicles}, units fulfilled ${PERSONNEL_STATE.unitsFulfilled}, ${PERSONNEL_STATE.action === 'assign' ? 'assigned' : 'planned'} ${PERSONNEL_STATE.action === 'assign' ? PERSONNEL_STATE.assignedCount : PERSONNEL_STATE.plannedCount}, need training ${PERSONNEL_STATE.trainingShortfall}, unfilled ${PERSONNEL_STATE.assignmentShortfall}.`,
                (
                    hasTargetShortfall
                    || PERSONNEL_STATE.trainingShortfall
                    || PERSONNEL_STATE.assignmentShortfall
                )
                    ? 'error'
                    : 'done'
            );

            if (
                PERSONNEL_STATE.mode === 'single'
                && PERSONNEL_STATE.lastStationReport
            ) {
                scrollPersonnelTo(
                    'mc-personnel-after-action-section'
                );
            }
        }
    }

    function prunePersonnelTrainingRegistry(
        registry,
        now = Date.now(),
        maximumVehicles = PERSONNEL_TRAINING_REGISTRY_MAX_VEHICLES
    ) {
        const sourceVehicles = registry?.vehicles && typeof registry.vehicles === 'object'
            ? registry.vehicles
            : {};
        const cutoff = now - PERSONNEL_TRAINING_REGISTRY_MAX_AGE_MS;
        const validEntries = Object.entries(sourceVehicles)
            .filter(([vehicleId, entry]) => {
                const updatedAt = Number(entry?.updatedAt || 0);
                return Boolean(
                    vehicleId
                    && entry
                    && typeof entry === 'object'
                    && Number.isFinite(updatedAt)
                    && updatedAt >= cutoff
                );
            })
            .sort((left, right) => Number(right[1]?.updatedAt || 0) - Number(left[1]?.updatedAt || 0));

        const retainedEntries = validEntries.slice(0, Math.max(0, Number(maximumVehicles) || 0));
        const vehicles = Object.fromEntries(retainedEntries);
        const originalCount = Object.keys(sourceVehicles).length;
        const retainedCount = retainedEntries.length;

        registry.vehicles = vehicles;

        return {
            originalCount,
            retainedCount,
            removedCount: Math.max(0, originalCount - retainedCount)
        };
    }

    function savePersonnelTrainingRegistry(registry) {
        const now = Date.now();
        const sourceVehicles = registry?.vehicles && typeof registry.vehicles === 'object'
            ? registry.vehicles
            : {};
        const sourceCount = Object.keys(sourceVehicles).length;
        const lastPrunedAt = Number(registry?.lastPrunedAt || 0);
        const shouldPrune = sourceCount > PERSONNEL_TRAINING_REGISTRY_MAX_VEHICLES
            || !Number.isFinite(lastPrunedAt)
            || now - lastPrunedAt >= PERSONNEL_TRAINING_REGISTRY_PRUNE_INTERVAL_MS;
        const primaryPrune = shouldPrune
            ? prunePersonnelTrainingRegistry(
                registry,
                now,
                PERSONNEL_TRAINING_REGISTRY_MAX_VEHICLES
            )
            : {
                originalCount: sourceCount,
                retainedCount: sourceCount,
                removedCount: 0
            };

        if (shouldPrune) registry.lastPrunedAt = now;

        try {
            localStorage.setItem(
                PERSONNEL_TRAINING_REGISTRY_STORAGE_KEY,
                JSON.stringify(registry)
            );

            return {
                saved: true,
                pruned: primaryPrune.removedCount,
                retained: primaryPrune.retainedCount,
                quotaRetry: false
            };
        } catch (error) {
            const isQuotaError = error?.name === 'QuotaExceededError'
                || error?.name === 'NS_ERROR_DOM_QUOTA_REACHED'
                || Number(error?.code) === 22
                || Number(error?.code) === 1014;

            if (!isQuotaError) throw error;

            const retryPrune = prunePersonnelTrainingRegistry(
                registry,
                now,
                PERSONNEL_TRAINING_REGISTRY_QUOTA_RETRY_MAX_VEHICLES
            );
            registry.lastPrunedAt = now;

            localStorage.setItem(
                PERSONNEL_TRAINING_REGISTRY_STORAGE_KEY,
                JSON.stringify(registry)
            );

            return {
                saved: true,
                pruned: Math.max(primaryPrune.removedCount, retryPrune.removedCount),
                retained: retryPrune.retainedCount,
                quotaRetry: true
            };
        }
    }

    function createEmptyPersonnelTrainingRegistry() {
        return {
            schemaVersion: PERSONNEL_TRAINING_REGISTRY_SCHEMA_VERSION,
            sourceVersion: PERSONNEL_VERSION,
            updatedAt: 0,
            lastPrunedAt: 0,
            vehicles: {}
        };
    }

    function readPersonnelTrainingRegistry() {
        if (PERSONNEL_TRAINING_REGISTRY_CACHE) {
            return PERSONNEL_TRAINING_REGISTRY_CACHE;
        }

        const emptyRegistry = createEmptyPersonnelTrainingRegistry();

        try {
            const parsed = JSON.parse(
                localStorage.getItem(PERSONNEL_TRAINING_REGISTRY_STORAGE_KEY) || 'null'
            );

            if (!parsed || typeof parsed !== 'object' || typeof parsed.vehicles !== 'object') {
                PERSONNEL_TRAINING_REGISTRY_CACHE = emptyRegistry;
                return PERSONNEL_TRAINING_REGISTRY_CACHE;
            }

            PERSONNEL_TRAINING_REGISTRY_CACHE = {
                ...emptyRegistry,
                ...parsed,
                vehicles: { ...parsed.vehicles }
            };

            prunePersonnelTrainingRegistry(PERSONNEL_TRAINING_REGISTRY_CACHE);
            PERSONNEL_TRAINING_REGISTRY_CACHE.lastPrunedAt = Date.now();
            return PERSONNEL_TRAINING_REGISTRY_CACHE;
        } catch (_error) {
            PERSONNEL_TRAINING_REGISTRY_CACHE = emptyRegistry;
            return PERSONNEL_TRAINING_REGISTRY_CACHE;
        }
    }

    function dispatchPersonnelTrainingRegistryUpdate(eventDetail) {
        if (!eventDetail) return;

        try {
            window.dispatchEvent(new CustomEvent(
                'mc-personnel-training-registry-updated',
                { detail: eventDetail }
            ));
        } catch (_eventError) {}
    }

    function flushPersonnelTrainingRegistry(silent = false) {
        if (PERSONNEL_TRAINING_REGISTRY_FLUSH_TIMER != null) {
            clearTimeout(PERSONNEL_TRAINING_REGISTRY_FLUSH_TIMER);
            PERSONNEL_TRAINING_REGISTRY_FLUSH_TIMER = null;
        }

        if (!PERSONNEL_TRAINING_REGISTRY_DIRTY || !PERSONNEL_TRAINING_REGISTRY_CACHE) {
            return { saved: false, pruned: 0, retained: 0, quotaRetry: false };
        }

        try {
            const registrySave = savePersonnelTrainingRegistry(PERSONNEL_TRAINING_REGISTRY_CACHE);
            PERSONNEL_TRAINING_REGISTRY_DIRTY = false;

            const pendingEvent = PERSONNEL_TRAINING_REGISTRY_PENDING_EVENT;
            PERSONNEL_TRAINING_REGISTRY_PENDING_EVENT = null;
            dispatchPersonnelTrainingRegistryUpdate(pendingEvent);

            if (!silent) {
                personnelDebug(
                    `Shared training register saved: retained=${registrySave.retained} | pruned=${registrySave.pruned}${registrySave.quotaRetry ? ' | quota retry used' : ''}`
                );
            }

            return registrySave;
        } catch (error) {
            if (!silent) {
                personnelLog(`Shared training register could not be saved: ${error?.message || error}`, 'error');
            }
            return { saved: false, pruned: 0, retained: 0, quotaRetry: false, error };
        }
    }

    function schedulePersonnelTrainingRegistryFlush() {
        if (PERSONNEL_TRAINING_REGISTRY_FLUSH_TIMER != null) return;

        PERSONNEL_TRAINING_REGISTRY_FLUSH_TIMER = setTimeout(() => {
            PERSONNEL_TRAINING_REGISTRY_FLUSH_TIMER = null;
            flushPersonnelTrainingRegistry(false);
        }, PERSONNEL_TRAINING_REGISTRY_FLUSH_DELAY_MS);
    }

    function countPersonnelTrainingCodes(
        assignedPersonnel
    ) {
        const counts = {};

        (
            Array.isArray(
                assignedPersonnel
            )
                ? assignedPersonnel
                : []
        ).forEach(person => {
            const uniqueCodes =
                new Set(
                    (
                        Array.isArray(
                            person?.trainingCodes
                        )
                            ? person.trainingCodes
                            : []
                    )
                        .map(String)
                        .filter(Boolean)
                );

            uniqueCodes.forEach(code => {
                counts[code] =
                    Number(
                        counts[code] ||
                        0
                    ) + 1;
            });
        });

        return counts;
    }


    function getPersonnelTrainingCombinationKey(trainingCodes) {
        return Array.from(
            new Set(
                (Array.isArray(trainingCodes) ? trainingCodes : [])
                    .map(String)
                    .filter(Boolean)
            )
        )
            .sort()
            .join('+');
    }

    function countPersonnelTrainingCombinations(assignedPersonnel) {
        const combinations = [
            ['traffic_police', 'swat']
        ];
        const counts = {};

        combinations.forEach(requiredCodes => {
            const key = getPersonnelTrainingCombinationKey(requiredCodes);
            counts[key] = (
                Array.isArray(assignedPersonnel)
                    ? assignedPersonnel
                    : []
            ).filter(person => {
                const trainingSet = new Set(
                    Array.isArray(person?.trainingCodes)
                        ? person.trainingCodes.map(String)
                        : []
                );
                return requiredCodes.every(code => trainingSet.has(code));
            }).length;
        });

        return counts;
    }

    function publishPersonnelVehicleTrainingRegistry({
        station,
        vehicles,
        personnel,
        source = 'scan',
        pruneMissingVehicles = true
    }) {
        const stationVehicles = Array.isArray(vehicles)
            ? vehicles.filter(vehicle => vehicle?.vehicleId)
            : [];

        if (!stationVehicles.length) return 0;

        const registry = readPersonnelTrainingRegistry();
        const now = Date.now();
        const currentVehicleIds = new Set(
            stationVehicles.map(vehicle => String(vehicle.vehicleId))
        );
        const processedTypeIds = new Set(
            stationVehicles.map(vehicle => String(vehicle.vehicleTypeId || ''))
        );

        if (pruneMissingVehicles) {
            Object.entries(registry.vehicles).forEach(([vehicleId, entry]) => {
                if (String(entry?.stationHref || '') !== String(station?.href || '')) return;
                if (!processedTypeIds.has(String(entry?.vehicleTypeId || ''))) return;
                if (!currentVehicleIds.has(String(vehicleId))) delete registry.vehicles[vehicleId];
            });
        }

        stationVehicles.forEach(vehicle => {
            const assignedPersonnel = getPersonnelAssignedToVehicle(personnel, vehicle);
            const vehicleId = String(vehicle.vehicleId);

            registry.vehicles[vehicleId] = {
                vehicleId,
                vehicleName: String(vehicle.name || ''),
                vehicleTypeId: String(vehicle.vehicleTypeId || ''),
                stationName: String(station?.displayName || station?.stationName || ''),
                stationHref: String(station?.href || ''),
                assignedPersonnelCount: assignedPersonnel.length,
                assignmentScanComplete: true,
                personnelRowsSeen: Array.isArray(personnel) ? personnel.length : 0,
                trainingCounts: countPersonnelTrainingCodes(assignedPersonnel),
                trainingCombinationCounts: countPersonnelTrainingCombinations(assignedPersonnel),
                updatedAt: now,
                source: String(source)
            };
        });

        registry.schemaVersion = PERSONNEL_TRAINING_REGISTRY_SCHEMA_VERSION;
        registry.sourceVersion = PERSONNEL_VERSION;
        registry.updatedAt = now;
        PERSONNEL_TRAINING_REGISTRY_DIRTY = true;
        PERSONNEL_TRAINING_REGISTRY_PENDING_EVENT = {
            stationName: station?.displayName || '',
            vehicleCount: stationVehicles.length,
            updatedAt: now
        };

        const finalSnapshot = /final-verification|station-complete/i.test(String(source));
        if (finalSnapshot) flushPersonnelTrainingRegistry(false);
        else schedulePersonnelTrainingRegistryFlush();

        personnelDebug(
            `Shared training register cache updated: ${stationVehicles.length} vehicle(s) at ${station?.displayName || 'station'} | source=${source}${finalSnapshot ? ' | flushed' : ' | write queued'}`
        );

        return stationVehicles.length;
    }
    function getPersonnelAssignmentIndex(personnel) {
        if (!Array.isArray(personnel)) {
            return { byVehicleId: new Map(), byVehicleName: new Map() };
        }

        const cached = PERSONNEL_ASSIGNMENT_INDEX_CACHE.get(personnel);
        if (cached) return cached;

        const byVehicleId = new Map();
        const byVehicleName = new Map();

        personnel.forEach(person => {
            const vehicleId = String(person?.assignedVehicleId || '');
            const vehicleName = normalizePersonnelVehicleName(person?.assignedVehicleName || '');

            if (vehicleId) {
                if (!byVehicleId.has(vehicleId)) byVehicleId.set(vehicleId, []);
                byVehicleId.get(vehicleId).push(person);
            }

            if (vehicleName) {
                if (!byVehicleName.has(vehicleName)) byVehicleName.set(vehicleName, []);
                byVehicleName.get(vehicleName).push(person);
            }
        });

        const index = { byVehicleId, byVehicleName };
        PERSONNEL_ASSIGNMENT_INDEX_CACHE.set(personnel, index);
        return index;
    }

    function getPersonnelAssignedToVehicle(personnel, vehicle) {
        if (!Array.isArray(personnel) || !vehicle) return [];

        const index = getPersonnelAssignmentIndex(personnel);
        const vehicleId = String(vehicle.vehicleId || '');
        const vehicleNameKey = normalizePersonnelVehicleName(vehicle.name || '');
        const byId = vehicleId ? (index.byVehicleId.get(vehicleId) || []) : [];
        const byName = vehicleNameKey ? (index.byVehicleName.get(vehicleNameKey) || []) : [];

        if (!byId.length) return byName;
        if (!byName.length || byName === byId) return byId;

        const result = byId.slice();
        const seen = new Set(result.map(person => String(person.personnelId || '')));
        byName.forEach(person => {
            const personnelId = String(person.personnelId || '');
            if (!seen.has(personnelId)) {
                seen.add(personnelId);
                result.push(person);
            }
        });
        return result;
    }

    async function processOnePersonnelStation(station) {
        const profile = getPersonnelProfileDefinition();
        if (profile?.engine === 'police') {
            return processOnePoliceStation(station, profile);
        }
        return processOneMedicalCriticalCareStation(station);
    }


    function getPoliceTrainingLabel(
        trainingCode
    ) {
        return (
            POLICE_TRAINING_LABELS[
                String(
                    trainingCode ||
                    ''
                )
            ] ||
            String(
                trainingCode ||
                ''
            )
                .replace(
                    /_/g,
                    ' '
                )
                .replace(
                    /\b\w/g,
                    character =>
                        character
                            .toUpperCase()
                )
        );
    }

    function getPersonnelMissingTrainingForRule(
        person,
        rule
    ) {
        const codes =
            new Set(
                Array.isArray(
                    person?.trainingCodes
                )
                    ? person.trainingCodes
                    : []
            );

        return (
            Array.isArray(
                rule?.trainingAll
            )
                ? rule.trainingAll
                : []
        )
            .filter(
                code =>
                    !codes.has(code)
            )
            .map(
                getPoliceTrainingLabel
            );
    }

    function buildPoliceRuleTrainingGapSummary(
        personnel,
        rule,
        requiredPositions
    ) {
        const required = Math.max(0, Number(requiredPositions) || 0);
        const counts = getVisiblePersonnelTrainingCounts(personnel);

        return (Array.isArray(rule?.trainingAll) ? rule.trainingAll : []).map(code => {
            const visible = Number(counts.get(String(code)) || 0);
            return {
                code: String(code),
                label: getPoliceTrainingLabel(code),
                required,
                visible,
                missing: Math.max(0, required - visible)
            };
        });
    }

    function formatPoliceTrainingGapSummary(
        trainingGaps
    ) {
        const missing =
            (
                Array.isArray(
                    trainingGaps
                )
                    ? trainingGaps
                    : []
            ).filter(
                item =>
                    Number(
                        item?.missing ||
                        0
                    ) >
                    0
            );

        if (!missing.length) {
            return 'None';
        }

        return missing
            .map(
                item =>
                    `${item.label} x${item.missing}`
            )
            .join(', ');
    }

    function formatVehicleOccupantTrainingGaps(
        occupantTrainingGaps
    ) {
        const entries =
            Array.isArray(
                occupantTrainingGaps
            )
                ? occupantTrainingGaps
                : [];

        if (!entries.length) {
            return '';
        }

        return entries
            .map(entry => {
                return (
                    `${entry.name}: ` +
                    `${entry.missingTraining.join(', ')}`
                );
            })
            .join('; ');
    }

    function getPersonnelTrainingSet(person) {
        if (!person || typeof person !== 'object') return new Set();

        const cached = PERSONNEL_TRAINING_SET_CACHE.get(person);
        if (cached) return cached;

        const trainingSet = new Set(
            Array.isArray(person.trainingCodes)
                ? person.trainingCodes.map(String)
                : []
        );
        PERSONNEL_TRAINING_SET_CACHE.set(person, trainingSet);
        return trainingSet;
    }

    function getVisiblePersonnelTrainingCounts(personnel) {
        if (!Array.isArray(personnel)) return new Map();

        const cached = PERSONNEL_VISIBLE_TRAINING_COUNTS_CACHE.get(personnel);
        if (cached) return cached;

        const counts = new Map();
        personnel.forEach(person => {
            getPersonnelTrainingSet(person).forEach(code => {
                counts.set(code, Number(counts.get(code) || 0) + 1);
            });
        });

        PERSONNEL_VISIBLE_TRAINING_COUNTS_CACHE.set(personnel, counts);
        return counts;
    }

    function personnelMatchesRule(person, rule) {
        const requiredCodes = Array.isArray(rule?.trainingAll) ? rule.trainingAll : [];
        if (!requiredCodes.length) return true;

        const trainingSet = getPersonnelTrainingSet(person);
        return requiredCodes.every(code => trainingSet.has(code));
    }

    function sortPersonnelCandidatesForRule(candidates, rule) {
        return candidates.slice().sort((left, right) => {
            const leftReserved = rule.preferWithout.some(code => left.trainingCodes.includes(code)) ? 1 : 0;
            const rightReserved = rule.preferWithout.some(code => right.trainingCodes.includes(code)) ? 1 : 0;
            if (leftReserved !== rightReserved) return leftReserved - rightReserved;

            const extraDifference = left.trainingCodes.length - right.trainingCodes.length;
            if (extraDifference) return extraDifference;
            return String(left.name || '').localeCompare(String(right.name || ''), 'en-GB', { numeric: true });
        });
    }

    function getPersonnelVehicleQueue(doc, allowedTypeIds) {
        const allowed = new Set((allowedTypeIds || []).map(String));
        const allowAllVehicleTypes = allowed.size === 0;
        const seen = new Set();
        const queue = [];

        for (const row of [...doc.querySelectorAll('#vehicle_table tr')]) {
            const image = row.querySelector('img[vehicle_type_id]');
            const vehicleTypeId = image?.getAttribute('vehicle_type_id') || '';
            if (!allowAllVehicleTypes && !allowed.has(vehicleTypeId)) continue;

            const vehicleLinks = [...row.querySelectorAll('a[href*="/vehicles/"]')];
            const plainVehicleLink = vehicleLinks.find(link => /^\/vehicles\/\d+\/?(?:[?#].*)?$/.test(link.getAttribute('href') || ''));
            const editLink = vehicleLinks.find(link => /\/vehicles\/\d+\/edit(?:[/?#]|$)/.test(link.getAttribute('href') || ''));
            const directAssignmentLink = vehicleLinks.find(link => /\/vehicles\/\d+\/zuweisung(?:[/?#]|$)/.test(link.getAttribute('href') || ''));
            const vehicleId = [plainVehicleLink, editLink, directAssignmentLink]
                .map(link => getVehicleIdFromHref(link?.getAttribute('href') || ''))
                .find(Boolean) || '';

            if (!vehicleId || seen.has(vehicleId)) continue;
            seen.add(vehicleId);

            const occupancy = parsePersonnelVehicleOccupancy(row);
            const nameSource = plainVehicleLink || vehicleLinks.find(link => cleanText(link.textContent || ''));
            queue.push({
                vehicleId,
                vehicleTypeId,
                name: cleanText(nameSource?.textContent || row.textContent || '') || `${TYPE_ID_TO_VEHICLE_TYPE[vehicleTypeId] || 'Vehicle'} ${vehicleId}`,
                assignmentHref: directAssignmentLink?.getAttribute('href') || `/vehicles/${vehicleId}/zuweisung`,
                assignedCount: occupancy.assignedCount,
                maxCount: occupancy.maxCount
            });
        }

        queue.sort((left, right) => left.name.localeCompare(right.name, 'en-GB', { numeric: true, sensitivity: 'base' }));
        return queue;
    }

    function sortPersonnelVehiclesForStationTarget(
        vehicles,
        personnel,
        rule
    ) {
        return (
            Array.isArray(vehicles)
                ? vehicles.slice()
                : []
        ).sort((left, right) => {
            const getState = vehicle => {
                const assigned =
                    getPersonnelAssignedToVehicle(
                        personnel,
                        vehicle
                    );

                const qualified =
                    assigned.filter(
                        person =>
                            personnelMatchesRule(
                                person,
                                rule
                            )
                    ).length;

                const total = assigned.length;
                const capacity =
                    Math.max(
                        rule.target,
                        Number(vehicle.maxCount)
                        || rule.target
                    );

                return {
                    covered:
                        qualified >= rule.target,
                    qualified,
                    total,
                    seatsAvailable:
                        Math.max(
                            0,
                            capacity - total
                        )
                };
            };

            const leftState = getState(left);
            const rightState = getState(right);

            const leftRank =
                leftState.covered
                    ? 0
                    : leftState.seatsAvailable > 0
                        ? 1
                        : 2;

            const rightRank =
                rightState.covered
                    ? 0
                    : rightState.seatsAvailable > 0
                        ? 1
                        : 2;

            if (leftRank !== rightRank) {
                return leftRank - rightRank;
            }

            if (
                leftState.qualified
                !== rightState.qualified
            ) {
                return (
                    rightState.qualified
                    - leftState.qualified
                );
            }

            if (leftState.total !== rightState.total) {
                return leftState.total - rightState.total;
            }

            return String(
                left.name || ''
            ).localeCompare(
                String(right.name || ''),
                'en-GB',
                { numeric: true }
            );
        });
    }

    function selectPoliceRuleVehicles({ rule, allVehicles, personnel, reservedPersonnelIds, claimedVehicleIds, batch }) {
        const matchingVehicles = allVehicles.filter(vehicle => rule.vehicleTypeIds.includes(vehicle.vehicleTypeId) && !claimedVehicleIds.has(vehicle.vehicleId));
        if (!batch || !rule.sharedVehiclePool) return matchingVehicles;

        const existing = matchingVehicles.filter(vehicle =>
            getPersonnelAssignedToVehicle(personnel, vehicle).some(person => personnelMatchesRule(person, rule))
        );
        const existingIds = new Set(existing.map(vehicle => vehicle.vehicleId));
        const availableCount = personnel.filter(person =>
            person.available
            && !reservedPersonnelIds.has(person.personnelId)
            && personnelMatchesRule(person, rule)
        ).length;
        const additionalVehicleCount = Math.ceil(availableCount / Math.max(1, rule.target));
        const additional = matchingVehicles
            .filter(vehicle => !existingIds.has(vehicle.vehicleId))
            .sort((left, right) => {
                const leftOccupied = Number.isInteger(left.assignedCount) ? left.assignedCount : 0;
                const rightOccupied = Number.isInteger(right.assignedCount) ? right.assignedCount : 0;
                if (leftOccupied !== rightOccupied) return leftOccupied - rightOccupied;
                return left.name.localeCompare(right.name, 'en-GB', { numeric: true });
            })
            .slice(0, additionalVehicleCount);

        return [...existing, ...additional];
    }

    function calculatePersonnelQualificationShortfall(personnel, slotRules) {
        const people = (personnel || []).filter(person => person?.personnelId);
        const slots = Array.isArray(slotRules) ? slotRules : [];
        const personToSlot = new Map();
        const candidatesByRule = new Map();

        const getCandidates = rule => {
            if (!candidatesByRule.has(rule)) {
                candidatesByRule.set(
                    rule,
                    people.filter(person => personnelMatchesRule(person, rule))
                );
            }
            return candidatesByRule.get(rule);
        };

        const tryFillSlot = (slotIndex, seenPersonnel) => {
            const rule = slots[slotIndex];
            for (const person of getCandidates(rule)) {
                if (seenPersonnel.has(person.personnelId)) continue;
                seenPersonnel.add(person.personnelId);

                const previousSlot = personToSlot.get(person.personnelId);
                if (previousSlot === undefined || tryFillSlot(previousSlot, seenPersonnel)) {
                    personToSlot.set(person.personnelId, slotIndex);
                    return true;
                }
            }
            return false;
        };

        let matched = 0;
        for (let slotIndex = 0; slotIndex < slots.length; slotIndex++) {
            if (tryFillSlot(slotIndex, new Set())) matched++;
        }

        return Math.max(0, slots.length - matched);
    }

    async function processOnePoliceStation(station, profile) {
        const stationPage = await personnelFetchDocument(station.href, 14000);
        const rules = Array.isArray(profile.rules) ? profile.rules : [];
        const targetTypeIds = [...new Set(rules.flatMap(rule => rule.vehicleTypeIds))];
        const allVehicles = getPersonnelVehicleQueue(stationPage.doc, targetTypeIds);

        if (!allVehicles.length) {
            personnelLog('No vehicles mapped to the selected Police profile were found at this station.', 'debug');
            return {
                stationName: station.displayName,
                stationHref: station.href,
                profileLabel: profile.label,
                noTargetVehicles: true,
                vehicleCount: 0,
                ambulances: 0,
                required: 0,
                trained: 0,
                availableAtScan: 0,
                availableAtEnd: 0,
                initialQualifiedFilled: 0,
                finalQualifiedFilled: 0,
                initialCriticalFilled: 0,
                finalCriticalFilled: 0,
                trainingShortfall: 0,
                assignmentShortfall: 0,
                planned: 0,
                assigned: 0,
                fulfilledUnits: 0,
                vehiclesChecked: 0,
                afterActionVerified: true,
                verificationError: '',
                rules: [],
                vehicles: []
            };
        }

        const baselinePage = await personnelFetchDocument(allVehicles[0].assignmentHref, 14000);
        const baselineAssignment = parseVehicleAssignmentPage(baselinePage.doc, allVehicles[0].vehicleId);
        const personnel = baselineAssignment.rows;

        publishPersonnelVehicleTrainingRegistry({
            station,
            vehicles:
                allVehicles,
            personnel,
            source:
                'police-station-scan'
        });

        const reservedPersonnelIds = new Set();
        const claimedVehicleIds = new Set();
        const vehicleReports = [];
        const ruleReports = [];
        let required = 0;
        let trainingShortfall = 0;
        const qualificationSlots = [];
        let stationPlanned = 0;
        let stationAssigned = 0;
        let stationAssignmentShortfall = 0;
        let projectedFulfilledUnits = 0;

        const stationUnitsNeeded = getPersonnelUnitsRemaining();
        const stationUnitTargetReached = () =>
            Number.isFinite(stationUnitsNeeded)
            && projectedFulfilledUnits >= stationUnitsNeeded;

        const unionQualified = personnel.filter(person => rules.some(rule => personnelMatchesRule(person, rule)));
        const availableAtScan = unionQualified.filter(person => person.available).length;

        personnelLog(`Mapped Police vehicles at station: ${allVehicles.length}`, 'info');
        personnelLog(`Profile rule groups: ${rules.length} | Qualified personnel visible: ${unionQualified.length}`, 'info');
        if (Number.isFinite(stationUnitsNeeded)) {
            personnelLog(`Units still required before this station: ${stationUnitsNeeded}. Only fully covered vehicles count.`, 'info');
        }

        for (const rule of rules) {
            if (PERSONNEL_STATE.stopped || stationUnitTargetReached()) break;
            await waitIfPersonnelPaused();
            if (PERSONNEL_STATE.stopped || stationUnitTargetReached()) break;

            let ruleVehicles = selectPoliceRuleVehicles({
                rule,
                allVehicles,
                personnel,
                reservedPersonnelIds,
                claimedVehicleIds,
                batch: profile.batch === true
            });

            if (isPersonnelPerStationTargetMode()) {
                ruleVehicles =
                    sortPersonnelVehiclesForStationTarget(
                        ruleVehicles,
                        personnel,
                        rule
                    );
            }

            if (!ruleVehicles.length) {
                personnelDebug(`${rule.label}: no allocated ${rule.vehicleLabel} vehicles at ${station.displayName}.`);
                continue;
            }

            const ruleTrained = personnel.filter(person => personnelMatchesRule(person, rule)).length;
            const ruleReport = {
                ruleId: rule.id,
                label: rule.label,
                vehicleLabel: rule.vehicleLabel,
                target: rule.target,
                trainingLabel: rule.trainingLabel,
                vehicleCount: 0,
                required: 0,
                trained: ruleTrained,
                trainingShortfall: 0,
                trainingGaps: []
            };

            personnelLog(`${rule.label}: ${ruleVehicles.length} available ${rule.vehicleLabel}(s), target ${rule.target} per vehicle.`, 'station');

            for (let vehicleIndex = 0; vehicleIndex < ruleVehicles.length; vehicleIndex++) {
                if (PERSONNEL_STATE.stopped || stationUnitTargetReached()) break;
                await waitIfPersonnelPaused();
                if (PERSONNEL_STATE.stopped || stationUnitTargetReached()) break;

                const vehicle = ruleVehicles[vehicleIndex];
                claimedVehicleIds.add(vehicle.vehicleId);
                ruleReport.vehicleCount++;
                ruleReport.required += rule.target;
                required += rule.target;
                for (let slotIndex = 0; slotIndex < rule.target; slotIndex++) qualificationSlots.push(rule);

                setPersonnelUiValue('vehicle', vehicle.name || vehicle.vehicleId);
                setPersonnelUiValue('status', PERSONNEL_STATE.action === 'assign' ? 'Checking Police vehicle' : 'Building Police preview');
                personnelLog(`${rule.label} vehicle ${vehicleIndex + 1}/${ruleVehicles.length}: ${vehicle.name}`, 'station');

                const baselineAssigned =
                    getPersonnelAssignedToVehicle(
                        personnel,
                        vehicle
                    );

                let beforeTotal =
                    baselineAssigned.length;

                let beforeQualified =
                    baselineAssigned.filter(
                        person =>
                            personnelMatchesRule(
                                person,
                                rule
                            )
                    ).length;

                let occupantTrainingGaps =
                    baselineAssigned
                        .map(person => {
                            return {
                                name:
                                    String(
                                        person.name ||
                                        person.personnelId ||
                                        'Assigned person'
                                    ),
                                missingTraining:
                                    getPersonnelMissingTrainingForRule(
                                        person,
                                        rule
                                    )
                            };
                        })
                        .filter(
                            entry =>
                                entry
                                    .missingTraining
                                    .length >
                                0
                        );

                const plannedNames = [];
                const assignedNames = [];
                let liveAssignment = null;

                if (PERSONNEL_STATE.action === 'assign' && beforeQualified < rule.target) {
                    const livePage = await personnelFetchDocument(vehicle.assignmentHref, 14000);
                    liveAssignment = parseVehicleAssignmentPage(livePage.doc, vehicle.vehicleId);

                    if (!rule.vehicleTypeIds.includes(liveAssignment.vehicleTypeId)) {
                        personnelLog(`Skipped unexpected vehicle_type_id=${liveAssignment.vehicleTypeId || 'unknown'} for ${rule.label}.`, 'error');
                        const unfilled = Math.max(0, rule.target - beforeQualified);
                        stationAssignmentShortfall += unfilled;
                        vehicleReports.push({
                            vehicleId: vehicle.vehicleId,
                            vehicleTypeId: vehicle.vehicleTypeId,
                            name: vehicle.name,
                            ruleId: rule.id,
                            ruleLabel: rule.label,
                            trainingLabel: rule.trainingLabel,
                            target: rule.target,
                            beforeQualified,
                            beforeCritical: beforeQualified,
                            beforeTotal,
                            afterQualified: beforeQualified,
                            afterCritical: beforeQualified,
                            afterTotal: beforeTotal,
                            finalQualified: beforeQualified,
                            finalCritical: beforeQualified,
                            finalTotal: beforeTotal,
                            plannedNames,
                            assignedNames,
                            unfilled,
                            occupiedSeatBlock: 0,
                            verificationStatus: 'skipped'
                        });
                        continue;
                    }

                    beforeTotal = liveAssignment.totalAssigned.length;
                    beforeQualified = liveAssignment.totalAssigned.filter(person => personnelMatchesRule(person, rule)).length;
                }

                if (beforeQualified >= rule.target) {
                    personnelLog(`Already covered: ${beforeQualified}/${rule.target} ${rule.trainingLabel}.`, 'done');
                } else {
                    const seatCapacity = Math.max(rule.target, Number(vehicle.maxCount) || rule.target);
                    const seatsAvailable = Math.max(0, seatCapacity - beforeTotal);
                    const targetGap = Math.max(0, rule.target - beforeQualified);
                    const attemptCount = Math.min(targetGap, seatsAvailable);

                    if (!attemptCount && targetGap) {
                        personnelLog(`Cannot top up safely: ${beforeTotal}/${seatCapacity} seats are occupied and ${targetGap} qualified position(s) remain. Existing staff were preserved.`, 'error');
                    }

                    const sourceRows = PERSONNEL_STATE.action === 'assign' ? (liveAssignment?.rows || []) : personnel;
                    const candidates = sortPersonnelCandidatesForRule(
                        sourceRows.filter(person =>
                            person.available
                            && !reservedPersonnelIds.has(person.personnelId)
                            && personnelMatchesRule(person, rule)
                        ),
                        rule
                    ).slice(0, attemptCount);

                    candidates.forEach(person => reservedPersonnelIds.add(person.personnelId));

                    if (PERSONNEL_STATE.action === 'preview') {
                        candidates.forEach(person => plannedNames.push(person.name));
                        stationPlanned += candidates.length;
                        if (candidates.length) personnelLog(`Would assign: ${candidates.map(person => person.name).join(', ')}`, 'after');
                    } else {
                        const submittedCandidates = [];
                        for (const candidate of candidates) {
                            if (PERSONNEL_STATE.stopped) break;
                            await waitIfPersonnelPaused();
                            if (PERSONNEL_STATE.stopped) break;

                            personnelLog(`Assigning ${candidate.name} to ${vehicle.name}...`, 'after');
                            if (await submitPersonnelAssignment(candidate)) {
                                submittedCandidates.push(candidate);
                                personnelLog(`Assignment submitted: ${candidate.name}`, 'info');
                            } else {
                                personnelLog(`Assignment request failed: ${candidate.name}`, 'error');
                            }
                        }

                        if (submittedCandidates.length && !PERSONNEL_STATE.stopped) {
                            await waitPersonnelDelay(250);
                            const verificationPage = await personnelFetchDocument(vehicle.assignmentHref, 14000);
                            const verification = parseVehicleAssignmentPage(verificationPage.doc, vehicle.vehicleId);

                            publishPersonnelVehicleTrainingRegistry({
                                station,
                                vehicles:
                                    allVehicles,
                                personnel:
                                    verification.rows,
                                source:
                                    'police-vehicle-verification'
                            });

                            const verifiedIds = new Set(
                                verification.rows
                                    .filter(person => person.assignedHere && personnelMatchesRule(person, rule))
                                    .map(person => person.personnelId)
                            );

                            submittedCandidates.forEach(candidate => {
                                if (verifiedIds.has(candidate.personnelId)) {
                                    assignedNames.push(candidate.name);
                                    stationAssigned++;
                                    personnelLog(`Assigned and verified: ${candidate.name}`, 'done');
                                } else {
                                    personnelLog(`Assignment could not be verified: ${candidate.name}`, 'error');
                                }
                            });
                        }
                    }
                }

                const addedCount = PERSONNEL_STATE.action === 'preview' ? plannedNames.length : assignedNames.length;
                const afterQualified = Math.min(rule.target, beforeQualified + addedCount);
                const afterTotal = beforeTotal + addedCount;
                const unfilled = Math.max(0, rule.target - afterQualified);
                const seatCapacity = Math.max(rule.target, Number(vehicle.maxCount) || rule.target);
                const occupiedSeatBlock = Math.max(0, Math.min(rule.target - beforeQualified, Math.max(0, beforeTotal - beforeQualified) - Math.max(0, seatCapacity - rule.target)));
                stationAssignmentShortfall += unfilled;

                personnelLog(unfilled ? `Unfilled ${rule.trainingLabel} positions: ${unfilled}` : `Coverage complete: ${afterQualified}/${rule.target}`, unfilled ? 'error' : 'done');

                vehicleReports.push({
                    vehicleId: vehicle.vehicleId,
                    vehicleTypeId: vehicle.vehicleTypeId,
                    name: vehicle.name,
                    ruleId: rule.id,
                    ruleLabel: rule.label,
                    trainingLabel: rule.trainingLabel,
                    target: rule.target,
                    beforeQualified,
                    beforeCritical: beforeQualified,
                    beforeTotal,
                    afterQualified,
                    afterCritical: afterQualified,
                    afterTotal,
                    finalQualified: afterQualified,
                    finalCritical: afterQualified,
                    finalTotal: afterTotal,
                    plannedNames,
                    assignedNames,
                    unfilled,
                    occupiedSeatBlock,
                    occupantTrainingGaps,
                    verificationStatus: PERSONNEL_STATE.action === 'preview' ? 'projected' : 'individually-verified'
                });

                if (unfilled === 0) {
                    projectedFulfilledUnits++;
                    personnelLog(
                        Number.isFinite(stationUnitsNeeded)
                            ? `Unit target progress at this station: ${projectedFulfilledUnits}/${stationUnitsNeeded}.`
                            : `Fully covered units at this station: ${projectedFulfilledUnits}.`,
                        'done'
                    );
                }
            }

            if (ruleReport.vehicleCount) {
                ruleReport.trainingShortfall =
                    Math.max(
                        0,
                        ruleReport.required -
                        ruleTrained
                    );

                ruleReport.trainingGaps =
                    buildPoliceRuleTrainingGapSummary(
                        personnel,
                        rule,
                        ruleReport.required
                    );

                ruleReports.push(
                    ruleReport
                );
                if (ruleReport.trainingShortfall) {
                    personnelLog(
                        `${rule.label} training shortfall estimate for processed units: ${ruleReport.trainingShortfall}. Missing: ${formatPoliceTrainingGapSummary(ruleReport.trainingGaps)}.`,
                        'error'
                    );
                }
            }
        }

        let afterActionVerified = PERSONNEL_STATE.action === 'preview';
        let verificationError = '';
        let availableAtEnd = Math.max(0, availableAtScan - (PERSONNEL_STATE.action === 'preview' ? stationPlanned : stationAssigned));

        if (PERSONNEL_STATE.action === 'assign' && !PERSONNEL_STATE.stopped && vehicleReports.length) {
            setPersonnelUiValue('status', 'Final Police station verification');
            setPersonnelUiValue('vehicle', 'All mapped Police vehicles');
            personnelLog('Running final station-wide Police verification...', 'info');

            try {
                await waitPersonnelDelay(900);
                const finalPage = await personnelFetchDocument(allVehicles[0].assignmentHref, 14000);
                const finalAssignment = parseVehicleAssignmentPage(finalPage.doc, allVehicles[0].vehicleId);

                publishPersonnelVehicleTrainingRegistry({
                    station,
                    vehicles:
                        allVehicles,
                    personnel:
                        finalAssignment.rows,
                    source:
                        'police-final-verification'
                });

                availableAtEnd = finalAssignment.rows.filter(person => person.available && rules.some(rule => personnelMatchesRule(person, rule))).length;
                stationAssignmentShortfall = 0;

                vehicleReports.forEach(vehicleReport => {
                    const rule = rules.find(item => item.id === vehicleReport.ruleId);
                    const actualAssigned = getPersonnelAssignedToVehicle(finalAssignment.rows, vehicleReport);
                    const actualQualified = rule ? actualAssigned.filter(person => personnelMatchesRule(person, rule)).length : 0;
                    vehicleReport.afterQualified = actualQualified;
                    vehicleReport.afterCritical = actualQualified;
                    vehicleReport.finalQualified = actualQualified;
                    vehicleReport.finalCritical = actualQualified;
                    vehicleReport.afterTotal = actualAssigned.length;
                    vehicleReport.finalTotal = actualAssigned.length;
                    vehicleReport.unfilled =
                        Math.max(
                            0,
                            vehicleReport.target -
                            actualQualified
                        );

                    vehicleReport.occupantTrainingGaps =
                        rule
                            ? actualAssigned
                                .map(person => {
                                    return {
                                        name:
                                            String(
                                                person.name ||
                                                person.personnelId ||
                                                'Assigned person'
                                            ),
                                        missingTraining:
                                            getPersonnelMissingTrainingForRule(
                                                person,
                                                rule
                                            )
                                    };
                                })
                                .filter(
                                    entry =>
                                        entry
                                            .missingTraining
                                            .length >
                                        0
                                )
                            : [];

                    vehicleReport.verificationStatus = 'final-verified';
                    stationAssignmentShortfall += vehicleReport.unfilled;
                });

                afterActionVerified = true;
                personnelLog(`Final Police station verification passed. Unfilled positions: ${stationAssignmentShortfall}.`, stationAssignmentShortfall ? 'error' : 'done');
            } catch (error) {
                verificationError = error?.message || String(error);
                vehicleReports.forEach(vehicleReport => {
                    if (vehicleReport.verificationStatus !== 'skipped') vehicleReport.verificationStatus = 'individual-verification-only';
                });
                personnelLog(`Final Police station verification failed: ${verificationError}`, 'error');
            }
        }

        trainingShortfall = calculatePersonnelQualificationShortfall(personnel, qualificationSlots);

        let initialQualifiedFilled = vehicleReports.reduce((sum, vehicle) => sum + Number(vehicle.beforeQualified || 0), 0);
        let finalQualifiedFilled = vehicleReports.reduce((sum, vehicle) => sum + Number(vehicle.afterQualified || 0), 0);
        let fulfilledUnits = vehicleReports.filter(vehicle => Number(vehicle.unfilled || 0) === 0).length;

        const stationTarget =
            isPersonnelPerStationTargetMode()
                ? PERSONNEL_STATE.unitsRequired
                : 0;

        if (stationTarget > 0) {
            fulfilledUnits =
                Math.min(
                    stationTarget,
                    fulfilledUnits
                );

            if (rules.length === 1) {
                const targetPositions =
                    stationTarget * rules[0].target;

                required = targetPositions;
                trainingShortfall =
                    Math.max(
                        0,
                        targetPositions - unionQualified.length
                    );
                stationAssignmentShortfall =
                    Math.max(
                        0,
                        (
                            stationTarget - fulfilledUnits
                        ) * rules[0].target
                    );
                initialQualifiedFilled =
                    Math.min(
                        targetPositions,
                        initialQualifiedFilled
                    );
                finalQualifiedFilled =
                    Math.min(
                        targetPositions,
                        finalQualifiedFilled
                    );
            }
        }

        return {
            stationName: station.displayName,
            stationHref: station.href,
            personnelPageHref: baselinePage.href,
            profileLabel: profile.label,
            qualificationLabel: profile.batch ? 'Mapped Police qualifications' : (rules[0]?.trainingLabel || profile.label),
            vehicleCount: vehicleReports.length,
            ambulances: vehicleReports.length,
            required,
            trained: unionQualified.length,
            availableAtScan,
            availableAtEnd,
            initialQualifiedFilled,
            finalQualifiedFilled,
            initialCriticalFilled: initialQualifiedFilled,
            finalCriticalFilled: finalQualifiedFilled,
            trainingShortfall,
            assignmentShortfall: stationAssignmentShortfall,
            planned: stationPlanned,
            assigned: stationAssigned,
            fulfilledUnits,
            stationTarget,
            stationTargetFulfilled:
                stationTarget > 0
                    ? fulfilledUnits
                    : 0,
            stationTargetMet:
                stationTarget > 0
                    ? fulfilledUnits >= stationTarget
                    : null,
            stationTargetShortfallUnits:
                stationTarget > 0
                    ? Math.max(
                        0,
                        stationTarget - fulfilledUnits
                    )
                    : 0,
            vehiclesChecked: vehicleReports.length,
            afterActionVerified,
            verificationError,
            missingTrainingSummary:
                ruleReports
                    .flatMap(
                        ruleReport =>
                            ruleReport
                                .trainingGaps ||
                            []
                    ),
            rules: ruleReports,
            vehicles: vehicleReports
        };
    }

    function sortMedicalVehiclesForStationTarget(
        vehicles,
        personnel
    ) {
        return (
            Array.isArray(vehicles)
                ? vehicles.slice()
                : []
        ).sort((left, right) => {
            const getState = vehicle => {
                const assigned =
                    getPersonnelAssignedToVehicle(
                        personnel,
                        vehicle
                    );

                const critical =
                    assigned.filter(
                        person =>
                            person.trainingCodes.includes(
                                PERSONNEL_TRAINING_CODE
                            )
                    ).length;

                const total = assigned.length;

                return {
                    covered:
                        critical >=
                        PERSONNEL_TARGET_PER_VEHICLE,
                    critical,
                    total,
                    seatsAvailable:
                        Math.max(
                            0,
                            PERSONNEL_TARGET_PER_VEHICLE
                            - total
                        )
                };
            };

            const leftState = getState(left);
            const rightState = getState(right);

            const leftRank =
                leftState.covered
                    ? 0
                    : leftState.seatsAvailable > 0
                        ? 1
                        : 2;

            const rightRank =
                rightState.covered
                    ? 0
                    : rightState.seatsAvailable > 0
                        ? 1
                        : 2;

            if (leftRank !== rightRank) {
                return leftRank - rightRank;
            }

            if (
                leftState.critical
                !== rightState.critical
            ) {
                return (
                    rightState.critical
                    - leftState.critical
                );
            }

            return String(
                left.name || ''
            ).localeCompare(
                String(right.name || ''),
                'en-GB',
                { numeric: true }
            );
        });
    }

    async function processOneMedicalCriticalCareStation(station) {
        const stationPage = await personnelFetchDocument(station.href, 14000);
        const vehicles = getPersonnelAmbulanceQueue(stationPage.doc);

        if (!vehicles.length) {
            throw new Error('No Ambulance vehicles were found in the station vehicle table.');
        }

        // One Ambulance assignment page supplies the station-wide personnel snapshot.
        // Button state is the authoritative binding signal; the station vehicle table
        // supplies the initial occupied/max cross-check.
        const baselinePage = await personnelFetchDocument(vehicles[0].assignmentHref, 14000);
        const baselineAssignment = parseVehicleAssignmentPage(baselinePage.doc, vehicles[0].vehicleId);

        if (baselineAssignment.vehicleTypeId !== PERSONNEL_TARGET_VEHICLE_TYPE_ID) {
            throw new Error(`The personnel assignment page was not an Ambulance page (vehicle_type_id=${baselineAssignment.vehicleTypeId || 'unknown'}).`);
        }

        const personnel = baselineAssignment.rows;
        const trained = personnel.filter(person => person.trainingCodes.includes(PERSONNEL_TRAINING_CODE));
        const availableAtScan = trained.filter(person => person.available).length;

        const processingVehicles =
            isPersonnelPerStationTargetMode()
                ? sortMedicalVehiclesForStationTarget(
                    vehicles,
                    personnel
                )
                : vehicles;

        const reservedPersonnelIds = new Set();
        const vehicleReports = [];
        let required = 0;
        let trainingShortfall = 0;
        let stationPlanned = 0;
        let stationAssigned = 0;
        let stationAssignmentShortfall = 0;
        let projectedFulfilledUnits = 0;

        const stationUnitsNeeded = getPersonnelUnitsRemaining();
        const stationUnitTargetReached = () =>
            Number.isFinite(stationUnitsNeeded)
            && projectedFulfilledUnits >= stationUnitsNeeded;

        personnelLog(`Ambulances available: ${vehicles.length}`, 'info');
        personnelLog(`${PERSONNEL_TRAINING_LABEL} trained: ${trained.length} | Available at scan: ${availableAtScan}`, 'info');
        if (Number.isFinite(stationUnitsNeeded)) {
            personnelLog(`Units still required before this station: ${stationUnitsNeeded}. Only Ambulances reaching 2/2 Critical Care count.`, 'info');
        }
        personnelLog(
            PERSONNEL_STATE.action === 'preview'
                ? 'Low-impact preview: station occupancy is cross-checked against one Ambulance personnel page.'
                : 'Fast safe assignment: each Ambulance is read once, assignments are submitted in a small batch, then verified with one vehicle check and one final station-wide check.',
            'debug'
        );

        for (let vehicleIndex = 0; vehicleIndex < processingVehicles.length; vehicleIndex++) {
            if (PERSONNEL_STATE.stopped || stationUnitTargetReached()) break;
            await waitIfPersonnelPaused();
            if (PERSONNEL_STATE.stopped || stationUnitTargetReached()) break;

            const vehicle = processingVehicles[vehicleIndex];
            required += PERSONNEL_TARGET_PER_VEHICLE;

            setPersonnelUiValue('vehicle', vehicle.name || vehicle.vehicleId);
            setPersonnelUiValue('status', PERSONNEL_STATE.action === 'assign' ? 'Checking vehicle' : 'Building station preview');
            personnelLog(`Vehicle ${vehicleIndex + 1}/${processingVehicles.length}: ${vehicle.name || vehicle.vehicleId}`, 'station');

            const stationAssignedPeople = getPersonnelAssignedToVehicle(personnel, vehicle);
            const mappedTotal = stationAssignedPeople.length;
            const mappedCritical = stationAssignedPeople.filter(person => person.trainingCodes.includes(PERSONNEL_TRAINING_CODE)).length;
            const hasTableOccupancy = Number.isInteger(vehicle.assignedCount) && vehicle.assignedCount >= 0;

            let beforeTotal = hasTableOccupancy
                ? Math.min(vehicle.assignedCount, mappedTotal)
                : mappedTotal;
            let beforeCritical = Math.min(mappedCritical, beforeTotal);
            const plannedNames = [];
            const assignedNames = [];

            if (hasTableOccupancy && mappedTotal !== beforeTotal) {
                personnelDebug(
                    `${vehicle.name}: station table occupancy=${vehicle.assignedCount}, `
                    + `personnel snapshot mapped=${mappedTotal}. Initial count set to ${beforeTotal}.`
                );
            }

            if (beforeTotal === 0) beforeCritical = 0;

            // In live mode, read the specific Ambulance immediately before changing it.
            let liveAssignment = null;
            if (PERSONNEL_STATE.action === 'assign' && beforeCritical < PERSONNEL_TARGET_PER_VEHICLE && beforeTotal < PERSONNEL_TARGET_PER_VEHICLE) {
                const livePage = await personnelFetchDocument(vehicle.assignmentHref, 14000);
                liveAssignment = parseVehicleAssignmentPage(livePage.doc, vehicle.vehicleId);

                if (liveAssignment.vehicleTypeId !== PERSONNEL_TARGET_VEHICLE_TYPE_ID) {
                    personnelLog(`Skipped non-Ambulance assignment page: vehicle_type_id=${liveAssignment.vehicleTypeId || 'unknown'}`, 'error');
                    const skippedUnfilled = Math.max(0, PERSONNEL_TARGET_PER_VEHICLE - beforeCritical);
                    stationAssignmentShortfall += skippedUnfilled;
                    vehicleReports.push({
                        vehicleId: vehicle.vehicleId,
                        name: vehicle.name || `Vehicle ${vehicle.vehicleId}`,
                        beforeCritical,
                        beforeTotal,
                        finalCritical: beforeCritical,
                        finalTotal: beforeTotal,
                        afterCritical: beforeCritical,
                        afterTotal: beforeTotal,
                        plannedNames,
                        assignedNames,
                        unfilled: skippedUnfilled,
                        occupiedSeatBlock: 0,
                        verificationStatus: 'skipped'
                    });
                    continue;
                }

                beforeCritical = liveAssignment.criticalAssigned.length;
                beforeTotal = liveAssignment.totalAssigned.length;
            }

            if (beforeCritical >= PERSONNEL_TARGET_PER_VEHICLE) {
                personnelLog(`Already covered: ${beforeCritical}/${PERSONNEL_TARGET_PER_VEHICLE} Critical Care staff.`, 'done');
            } else {
                const seatsAvailable = Math.max(0, PERSONNEL_TARGET_PER_VEHICLE - beforeTotal);
                const targetGap = Math.max(0, PERSONNEL_TARGET_PER_VEHICLE - beforeCritical);
                const attemptCount = Math.min(targetGap, seatsAvailable);

                if (seatsAvailable === 0) {
                    personnelLog(`Cannot top up safely: ${beforeTotal}/${PERSONNEL_TARGET_PER_VEHICLE} seats are occupied, but only ${beforeCritical} occupant(s) have Critical Care. Existing staff were preserved.`, 'error');
                }

                if (PERSONNEL_STATE.action === 'preview') {
                    const candidates = trained
                        .filter(person => person.available && !reservedPersonnelIds.has(person.personnelId))
                        .slice(0, attemptCount);

                    candidates.forEach(person => {
                        reservedPersonnelIds.add(person.personnelId);
                        plannedNames.push(person.name);
                    });
                    stationPlanned += candidates.length;

                    if (candidates.length) {
                        personnelLog(`Would assign: ${candidates.map(person => person.name).join(', ')}`, 'after');
                    }
                } else {
                    // Use the live page already loaded for this Ambulance to select all
                    // required candidates. Submit them sequentially, then verify the whole
                    // batch with one fresh page request instead of reloading after every
                    // individual person.
                    const candidates = (liveAssignment?.availableCritical || [])
                        .filter(person => !reservedPersonnelIds.has(person.personnelId))
                        .slice(0, attemptCount);
                    const submittedCandidates = [];

                    candidates.forEach(person => reservedPersonnelIds.add(person.personnelId));

                    for (const candidate of candidates) {
                        if (PERSONNEL_STATE.stopped) break;
                        await waitIfPersonnelPaused();
                        if (PERSONNEL_STATE.stopped) break;

                        personnelLog(`Assigning ${candidate.name} to ${vehicle.name || vehicle.vehicleId}...`, 'after');
                        const submitted = await submitPersonnelAssignment(candidate);

                        if (submitted) {
                            submittedCandidates.push(candidate);
                            personnelLog(`Assignment submitted: ${candidate.name}`, 'info');
                        } else {
                            personnelLog(`Assignment request failed: ${candidate.name}`, 'error');
                        }
                    }

                    if (submittedCandidates.length && !PERSONNEL_STATE.stopped) {
                        await waitPersonnelDelay(250);
                        const verificationPage = await personnelFetchDocument(vehicle.assignmentHref, 14000);
                        const verification = parseVehicleAssignmentPage(verificationPage.doc, vehicle.vehicleId);
                        const verifiedIds = new Set(
                            verification.rows
                                .filter(person => person.assignedHere)
                                .map(person => person.personnelId)
                        );

                        submittedCandidates.forEach(candidate => {
                            if (verifiedIds.has(candidate.personnelId)) {
                                assignedNames.push(candidate.name);
                                stationAssigned++;
                                personnelLog(`Assigned and verified: ${candidate.name}`, 'done');
                            } else {
                                personnelLog(`Assignment could not be verified: ${candidate.name}`, 'error');
                            }
                        });
                    }
                }
            }

            const calculatedAfterCritical = PERSONNEL_STATE.action === 'preview'
                ? Math.min(PERSONNEL_TARGET_PER_VEHICLE, beforeCritical + plannedNames.length)
                : Math.min(PERSONNEL_TARGET_PER_VEHICLE, beforeCritical + assignedNames.length);
            const calculatedAfterTotal = PERSONNEL_STATE.action === 'preview'
                ? beforeTotal + plannedNames.length
                : beforeTotal + assignedNames.length;
            const calculatedUnfilled = Math.max(0, PERSONNEL_TARGET_PER_VEHICLE - calculatedAfterCritical);
            stationAssignmentShortfall += calculatedUnfilled;

            if (calculatedUnfilled) {
                personnelLog(`Unfilled Critical Care positions: ${calculatedUnfilled}`, 'error');
            } else {
                personnelLog(`Coverage complete: ${calculatedAfterCritical}/${PERSONNEL_TARGET_PER_VEHICLE}`, 'done');
            }

            vehicleReports.push({
                vehicleId: vehicle.vehicleId,
                name: vehicle.name || `Vehicle ${vehicle.vehicleId}`,
                beforeCritical,
                beforeTotal,
                finalCritical: calculatedAfterCritical,
                finalTotal: calculatedAfterTotal,
                afterCritical: calculatedAfterCritical,
                afterTotal: calculatedAfterTotal,
                plannedNames,
                assignedNames,
                unfilled: calculatedUnfilled,
                occupiedSeatBlock: Math.max(0, (PERSONNEL_TARGET_PER_VEHICLE - beforeCritical) - Math.max(0, PERSONNEL_TARGET_PER_VEHICLE - beforeTotal)),
                verificationStatus: PERSONNEL_STATE.action === 'preview' ? 'projected' : 'individually-verified'
            });

            if (calculatedUnfilled === 0) {
                projectedFulfilledUnits++;
                personnelLog(
                    Number.isFinite(stationUnitsNeeded)
                        ? `Unit target progress at this station: ${projectedFulfilledUnits}/${stationUnitsNeeded}.`
                        : `Fully covered Ambulances at this station: ${projectedFulfilledUnits}.`,
                    'done'
                );
            }
        }

        trainingShortfall = Math.max(0, required - trained.length);
        if (trainingShortfall) {
            personnelLog(`Training shortfall for processed Ambulances: ${trainingShortfall} additional personnel need ${PERSONNEL_TRAINING_LABEL} training.`, 'error');
        }

        let afterActionVerified = PERSONNEL_STATE.action === 'preview';
        let verificationError = '';
        let availableAtEnd = Math.max(0, availableAtScan - (PERSONNEL_STATE.action === 'preview' ? stationPlanned : stationAssigned));

        // Final station-wide verification. This is one additional request after the
        // station is complete and produces the actual after-action figures rather than
        // merely trusting the number of successful POSTs.
        if (PERSONNEL_STATE.action === 'assign' && !PERSONNEL_STATE.stopped && vehicleReports.length) {
            setPersonnelUiValue('status', 'Final station verification');
            setPersonnelUiValue('vehicle', 'Processed Ambulances');
            personnelLog('Running final station-wide after-action verification...', 'info');

            try {
                await waitPersonnelDelay(900);
                const finalPage = await personnelFetchDocument(vehicles[0].assignmentHref, 14000);
                const finalAssignment = parseVehicleAssignmentPage(finalPage.doc, vehicles[0].vehicleId);

                if (finalAssignment.vehicleTypeId !== PERSONNEL_TARGET_VEHICLE_TYPE_ID) {
                    throw new Error(`Final verification returned vehicle_type_id=${finalAssignment.vehicleTypeId || 'unknown'}.`);
                }

                availableAtEnd = finalAssignment.availableCritical.length;
                stationAssignmentShortfall = 0;

                vehicleReports.forEach(vehicleReport => {
                    const actualAssigned = getPersonnelAssignedToVehicle(finalAssignment.rows, vehicleReport);
                    const actualCritical = actualAssigned.filter(person => person.trainingCodes.includes(PERSONNEL_TRAINING_CODE)).length;
                    const actualTotal = actualAssigned.length;

                    vehicleReport.afterCritical = actualCritical;
                    vehicleReport.afterTotal = actualTotal;
                    vehicleReport.finalCritical = actualCritical;
                    vehicleReport.finalTotal = actualTotal;
                    vehicleReport.unfilled = Math.max(0, PERSONNEL_TARGET_PER_VEHICLE - actualCritical);
                    vehicleReport.verificationStatus = 'final-verified';
                    stationAssignmentShortfall += vehicleReport.unfilled;
                });

                afterActionVerified = true;
                personnelLog(`Final station verification passed. Unfilled positions: ${stationAssignmentShortfall}.`, stationAssignmentShortfall ? 'error' : 'done');
            } catch (error) {
                verificationError = error?.message || String(error);
                afterActionVerified = false;
                vehicleReports.forEach(vehicleReport => {
                    if (vehicleReport.verificationStatus !== 'skipped') {
                        vehicleReport.verificationStatus = 'individual-verification-only';
                    }
                });
                personnelLog(`Final station verification failed: ${verificationError}`, 'error');
            }
        }

        let initialCriticalFilled = vehicleReports.reduce((sum, vehicle) => sum + Number(vehicle.beforeCritical || 0), 0);
        let finalCriticalFilled = vehicleReports.reduce((sum, vehicle) => sum + Number(vehicle.afterCritical || 0), 0);
        let fulfilledUnits = vehicleReports.filter(vehicle => Number(vehicle.unfilled || 0) === 0).length;

        const stationTarget =
            isPersonnelPerStationTargetMode()
                ? PERSONNEL_STATE.unitsRequired
                : 0;

        if (stationTarget > 0) {
            fulfilledUnits =
                Math.min(
                    stationTarget,
                    fulfilledUnits
                );

            required =
                stationTarget
                * PERSONNEL_TARGET_PER_VEHICLE;

            trainingShortfall =
                Math.max(
                    0,
                    required - trained.length
                );

            stationAssignmentShortfall =
                Math.max(
                    0,
                    (
                        stationTarget - fulfilledUnits
                    ) * PERSONNEL_TARGET_PER_VEHICLE
                );

            initialCriticalFilled =
                Math.min(
                    required,
                    initialCriticalFilled
                );

            finalCriticalFilled =
                Math.min(
                    required,
                    finalCriticalFilled
                );
        }

        return {
            stationName: station.displayName,
            stationHref: station.href,
            personnelPageHref: baselinePage.href,
            profileLabel: 'Critical Care',
            qualificationLabel: PERSONNEL_TRAINING_LABEL,
            vehicleCount: vehicleReports.length,
            ambulances: vehicleReports.length,
            required,
            trained: trained.length,
            availableAtScan,
            availableAtEnd,
            initialQualifiedFilled: initialCriticalFilled,
            finalQualifiedFilled: finalCriticalFilled,
            initialCriticalFilled,
            finalCriticalFilled,
            trainingShortfall,
            assignmentShortfall: stationAssignmentShortfall,
            planned: stationPlanned,
            assigned: stationAssigned,
            fulfilledUnits,
            stationTarget,
            stationTargetFulfilled:
                stationTarget > 0
                    ? fulfilledUnits
                    : 0,
            stationTargetMet:
                stationTarget > 0
                    ? fulfilledUnits >= stationTarget
                    : null,
            stationTargetShortfallUnits:
                stationTarget > 0
                    ? Math.max(
                        0,
                        stationTarget - fulfilledUnits
                    )
                    : 0,
            vehiclesChecked: vehicleReports.length,
            afterActionVerified,
            verificationError,
            rules: [{
                ruleId: 'critical_care',
                label: 'Critical Care',
                vehicleLabel: PERSONNEL_TARGET_VEHICLE_LABEL,
                target: PERSONNEL_TARGET_PER_VEHICLE,
                trainingLabel: PERSONNEL_TRAINING_LABEL,
                vehicleCount: vehicleReports.length,
                required,
                trained: trained.length,
                trainingShortfall
            }],
            vehicles: vehicleReports.map(vehicle => ({
                ...vehicle,
                ruleId: 'critical_care',
                ruleLabel: 'Critical Care',
                trainingLabel: PERSONNEL_TRAINING_LABEL,
                target: PERSONNEL_TARGET_PER_VEHICLE,
                beforeQualified: vehicle.beforeCritical,
                afterQualified: vehicle.afterCritical,
                finalQualified: vehicle.finalCritical
            }))
        };
    }

    async function waitPersonnelDelay(delayMs) {
        const endAt = Date.now() + Math.max(0, Number(delayMs) || 0);
        while (Date.now() < endAt) {
            if (PERSONNEL_STATE.stopped) return;
            await sleep(Math.min(100, endAt - Date.now()));
        }
    }

    async function waitForPersonnelRequestSlot() {
        const elapsed = Date.now() - (PERSONNEL_STATE.lastRequestAt || 0);
        const waitMs = Math.max(0, PERSONNEL_REQUEST_GAP_MS - elapsed);
        if (waitMs) await waitPersonnelDelay(waitMs);
        if (PERSONNEL_STATE.stopped) throw new DOMException('Personnel run stopped', 'AbortError');
    }

    async function personnelFetchResponse(url, options = {}, timeoutMs = 12000) {
        await waitForPersonnelRequestSlot();

        const controller = new AbortController();
        PERSONNEL_STATE.activeController = controller;
        const timer = setTimeout(() => controller.abort(), timeoutMs);

        try {
            const response = await fetch(url, {
                credentials: 'same-origin',
                cache: 'no-store',
                redirect: 'follow',
                ...options,
                signal: controller.signal
            });
            PERSONNEL_STATE.lastRequestAt = Date.now();
            return response;
        } finally {
            clearTimeout(timer);
            if (PERSONNEL_STATE.activeController === controller) {
                PERSONNEL_STATE.activeController = null;
            }
        }
    }

    async function personnelFetchDocument(url, timeoutMs = 12000) {
        const response = await personnelFetchResponse(url, {
            headers: {
                'Accept': 'text/html,application/xhtml+xml'
            }
        }, timeoutMs);

        if (!response.ok) throw new Error(`Request returned HTTP ${response.status}: ${url}`);

        const html = await response.text();
        const doc = new DOMParser().parseFromString(html, 'text/html');
        return { response, doc, href: new URL(response.url || url, location.origin).pathname };
    }

    function parsePersonnelVehicleOccupancy(row) {
        const text = String(row?.textContent || '');
        const matches = [...text.matchAll(/\(\s*(\d+)\s*\/\s*(\d+)\s*\)/g)];
        const match = matches.at(-1);

        if (!match) {
            return { assignedCount: null, maxCount: null };
        }

        return {
            assignedCount: Number(match[1]),
            maxCount: Number(match[2])
        };
    }

    function normalizePersonnelVehicleName(value) {
        return cleanText(value)
            .replace(/\s+/g, ' ')
            .trim()
            .toUpperCase();
    }

    function getPersonnelAmbulanceQueue(doc) {
        const seen = new Set();
        const queue = [];
        const rows = [...doc.querySelectorAll('#vehicle_table tr')];
        let ambulanceRows = 0;

        for (const row of rows) {
            const image = row.querySelector('img[vehicle_type_id]');
            const vehicleTypeId = image?.getAttribute('vehicle_type_id') || '';
            if (vehicleTypeId !== PERSONNEL_TARGET_VEHICLE_TYPE_ID) continue;

            ambulanceRows++;

            const vehicleLinks = [...row.querySelectorAll('a[href*="/vehicles/"]')];
            const plainVehicleLink = vehicleLinks.find(link => {
                const href = link.getAttribute('href') || '';
                return /^\/vehicles\/\d+\/?(?:[?#].*)?$/.test(href);
            });
            const editLink = vehicleLinks.find(link => {
                const href = link.getAttribute('href') || '';
                return /\/vehicles\/\d+\/edit(?:[/?#]|$)/.test(href);
            });
            const directAssignmentLink = vehicleLinks.find(link => {
                const href = link.getAttribute('href') || '';
                return /\/vehicles\/\d+\/zuweisung(?:[/?#]|$)/.test(href);
            });

            // Prefer the normal vehicle-name link because it is tied directly to the
            // displayed row. Edit and personnel links are safe fallbacks.
            const idCandidates = [plainVehicleLink, editLink, directAssignmentLink]
                .map(link => getVehicleIdFromHref(link?.getAttribute('href') || ''))
                .filter(Boolean);
            const vehicleId = idCandidates[0] || '';

            if (!vehicleId || seen.has(vehicleId)) continue;
            seen.add(vehicleId);

            const distinctIds = [...new Set(idCandidates)];
            if (distinctIds.length > 1) {
                personnelDebug(`Ambulance row contains conflicting vehicle IDs (${distinctIds.join(', ')}). Using ${vehicleId}.`);
            }

            const assignmentHref = directAssignmentLink?.getAttribute('href') || `/vehicles/${vehicleId}/zuweisung`;
            const nameSource = plainVehicleLink
                || vehicleLinks.find(link => cleanText(link.textContent || ''))
                || null;
            const name = cleanText(nameSource?.textContent || row.textContent || '') || `Ambulance ${vehicleId}`;
            const occupancy = parsePersonnelVehicleOccupancy(row);

            queue.push({
                vehicleId,
                name,
                assignmentHref,
                assignedCount: occupancy.assignedCount,
                maxCount: occupancy.maxCount
            });
        }

        queue.sort((a, b) => a.name.localeCompare(b.name, undefined, {
            numeric: true,
            sensitivity: 'base'
        }));

        personnelDebug(`Vehicle table scan: ${rows.length} row(s), ${ambulanceRows} Ambulance row(s), ${queue.length} usable assignment route(s).`);
        queue.forEach(vehicle => {
            personnelDebug(`Ambulance detected: ${vehicle.name} | ID=${vehicle.vehicleId} | table occupancy=${vehicle.assignedCount ?? '?'} / ${vehicle.maxCount ?? '?'}`);
        });

        return queue;
    }


    function parseTrainingCodes(row) {
        const raw = row?.getAttribute('data-filterable-by') || '[]';
        try {
            const parsed = JSON.parse(raw);
            return Array.isArray(parsed) ? parsed.map(String) : [];
        } catch (_error) {
            return String(raw)
                .replace(/[\[\]"']/g, '')
                .split(',')
                .map(value => value.trim())
                .filter(Boolean);
        }
    }


    function parseVehicleAssignmentPage(doc, vehicleId) {
        const currentVehicleId = String(vehicleId || '');
        const vehicleTypeId = doc.querySelector('.vehicle_image_reload[vehicle_type_id]')?.getAttribute('vehicle_type_id') || '';
        const rows = [...doc.querySelectorAll('#personal_table tbody tr[data-filterable-by]')]
            .map(row => {
                const cells = [...row.children];
                const actionLink = row.querySelector(`a[href*="/vehicles/${currentVehicleId}/zuweisungDo/"]`)
                    || row.querySelector('a[href*="/zuweisungDo/"]');
                const personnelId = String(
                    actionLink?.getAttribute('personal_id') ||
                    row.id?.match(/personal_(\d+)/)?.[1] ||
                    actionLink?.getAttribute('href')?.match(/\/zuweisungDo\/(\d+)/)?.[1] ||
                    ''
                );
                const classes = actionLink ? [...actionLink.classList] : [];
                const assignedVehicleLink = [...row.querySelectorAll('a[href^="/vehicles/"]')].find(link => {
                    const href = link.getAttribute('href') || '';
                    return /^\/vehicles\/\d+\/?(?:[?#].*)?$/.test(href);
                });
                const detectedAssignedVehicleId = getVehicleIdFromHref(assignedVehicleLink?.getAttribute('href') || '');
                const actionText = cleanText(
                    actionLink?.innerText ||
                    actionLink?.textContent ||
                    actionLink?.value ||
                    ''
                );
                const assignedHere =
                    classes.includes('btn-assigned') ||
                    /remove\s+binding/i.test(actionText);
                const assignedElsewhere = classes.includes('btn-warning');
                const available = classes.includes('btn-success') && !assignedHere && !assignedElsewhere;

                // Do not treat a displayed "In a Vehicle" link as an active binding by
                // itself. On MissionChief, green btn-success rows can still carry an old
                // or preferred vehicle link. Actual bindings are identified only by:
                //   btn-assigned = assigned to the page's current vehicle
                //   btn-warning  = assigned to a different vehicle
                //   btn-success  = available to assign
                const assignedVehicleId = assignedHere
                    ? currentVehicleId
                    : (assignedElsewhere ? detectedAssignedVehicleId : '');

                return {
                    personnelId,
                    name: cleanText(cells[0]?.textContent || ''),
                    trainingText: cleanText(cells[1]?.textContent || ''),
                    trainingCodes: parseTrainingCodes(row),
                    assignedHere,
                    assignedVehicleId,
                    assignedVehicleName: assignedVehicleId ? cleanText(assignedVehicleLink?.textContent || '') : '',
                    available,
                    assignedElsewhere,
                    displayedVehicleId: detectedAssignedVehicleId,
                    assignHref: actionLink?.getAttribute('href') || ''
                };
            })
            .filter(person => person.personnelId);

        return {
            vehicleTypeId,
            rows,
            totalAssigned: rows.filter(person => person.assignedVehicleId === currentVehicleId),
            criticalAssigned: rows.filter(person => person.assignedVehicleId === currentVehicleId && person.trainingCodes.includes(PERSONNEL_TRAINING_CODE)),
            availableCritical: rows.filter(person => person.available && person.trainingCodes.includes(PERSONNEL_TRAINING_CODE))
        };
    }

    async function submitPersonnelAssignment(candidate) {
        if (!candidate.assignHref || PERSONNEL_STATE.stopped) return false;

        const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';
        const headers = {
            'Accept': 'text/html,application/xhtml+xml',
            'X-Requested-With': 'XMLHttpRequest'
        };
        if (csrfToken) headers['X-CSRF-Token'] = csrfToken;

        const response = await personnelFetchResponse(candidate.assignHref, {
            method: 'POST',
            headers
        }, 12000);

        if (!response.ok) {
            personnelDebug(`Assignment request HTTP ${response.status}: ${candidate.assignHref}`);
            return false;
        }

        // Consume the response so the request finishes cleanly. MissionChief normally
        // returns the updated personnel-row HTML, but the batch is verified using one
        // fresh vehicle page after all required people have been submitted.
        try {
            await response.text();
        } catch (_error) {}

        return true;
    }

    function getPersonnelReportResult(report) {
        if (report?.error) return 'ERROR';

        if (Number(report?.stationTarget || 0) > 0) {
            return report?.stationTargetMet
                ? 'TARGET MET'
                : 'TARGET SHORTFALL';
        }

        if (report?.noTargetVehicles) return 'NO TARGET VEHICLES';
        if (Number(report?.assignmentShortfall || 0) > 0) return 'SHORTFALL';
        return 'COMPLETE';
    }

    function getPersonnelReportQualificationLabel(report) {
        return report?.qualificationLabel || getPersonnelProfileDefinition()?.label || 'Required qualification';
    }

    function getPersonnelReportVehicleCount(report) {
        return Number(report?.vehicleCount ?? report?.ambulances ?? report?.vehiclesChecked ?? 0);
    }

    function getPersonnelReportInitialFilled(report) {
        return Number(report?.initialQualifiedFilled ?? report?.initialCriticalFilled ?? 0);
    }

    function getPersonnelReportFinalFilled(report) {
        return Number(report?.finalQualifiedFilled ?? report?.finalCriticalFilled ?? 0);
    }

    function buildStationAfterActionText(report) {
        if (!report) return 'No station report is available yet.';

        const isAssign = PERSONNEL_STATE.action === 'assign';
        const service = getPersonnelServiceDefinition();
        const profile = getPersonnelProfileDefinition();
        const result = getPersonnelReportResult(report);
        const qualificationLabel = getPersonnelReportQualificationLabel(report);
        const lines = [
            `${service.label.toUpperCase()} — ${profile.label.toUpperCase()} ${isAssign ? 'STATION AFTER-ACTION REPORT' : 'STATION PREVIEW REPORT'}`,
            `Station: ${report.stationName || 'Unknown'}`,
            `Result: ${result}`,
            `Generated: ${new Date().toLocaleString('en-GB')}`,
            ''
        ];

        if (report.error) {
            lines.push(`ERROR: ${report.error}`);
            return lines.join('\n');
        }

        if (report.noTargetVehicles) {
            lines.push('No vehicles mapped to this profile were found at the station. No assignments were changed.');
            return lines.join('\n');
        }

        const verificationText = isAssign
            ? (report.afterActionVerified ? 'PASSED - final station state re-read' : `PARTIAL - ${report.verificationError || 'final station re-read was not verified'}`)
            : 'PREVIEW PROJECTION - no assignments changed';

        lines.push(
            `Final verification: ${verificationText}`,
            `Mapped vehicles checked: ${getPersonnelReportVehicleCount(report)}`,
            ...(
                Number(report.stationTarget || 0) > 0
                    ? [
                        `Station unit target: ${report.stationTarget}`,
                        `Station target result: ${report.stationTargetMet ? 'PASSED' : 'SHORT'} — ${Number(report.stationTargetFulfilled || 0)}/${report.stationTarget}`,
                        `Additional fully staffed units needed: ${Number(report.stationTargetShortfallUnits || 0)}`
                    ]
                    : []
            ),
            `Units fully covered at this station: ${Number(report.fulfilledUnits || 0)}`,
            `Required qualified positions: ${Number(report.required || 0)}`,
            `${qualificationLabel} personnel visible: ${Number(report.trained || 0)}`,
            `Available qualified before action: ${Number(report.availableAtScan || 0)}`,
            `Available qualified after action: ${Number(report.availableAtEnd || 0)}`,
            `Qualified positions before: ${getPersonnelReportInitialFilled(report)}/${Number(report.required || 0)}`,
            `${isAssign ? 'Qualified positions after' : 'Projected qualified positions'}: ${getPersonnelReportFinalFilled(report)}/${Number(report.required || 0)}`,
            `${isAssign ? 'Personnel assigned and verified' : 'Assignments planned'}: ${isAssign ? Number(report.assigned || 0) : Number(report.planned || 0)}`,
            `Qualification shortfall estimate: ${Number(report.trainingShortfall || 0)}`,
            `Missing training by qualification: ${formatPoliceTrainingGapSummary(report.missingTrainingSummary)}`,
            `Unfilled required positions after action: ${Number(report.assignmentShortfall || 0)}`
        );

        if (Array.isArray(report.rules) && report.rules.length > 1) {
            lines.push('', 'RULE GROUPS');
            report.rules.forEach(rule => {
                lines.push(
                    `  - ${rule.label}: ${rule.vehicleCount} ${rule.vehicleLabel}(s) | target ${rule.target} each | required ${rule.required} | trained ${rule.trained} | training shortfall ${rule.trainingShortfall} | missing ${formatPoliceTrainingGapSummary(rule.trainingGaps)}`
                );
            });
        }

        lines.push('', 'VEHICLE RESULTS');

        report.vehicles.forEach(vehicle => {
            const names = isAssign ? vehicle.assignedNames : vehicle.plannedNames;
            const afterLabel = isAssign
                ? (vehicle.verificationStatus === 'final-verified' ? 'final verified' : 'after action')
                : 'projected';
            const target = Number(vehicle.target || PERSONNEL_TARGET_PER_VEHICLE);
            const beforeQualified = Number(vehicle.beforeQualified ?? vehicle.beforeCritical ?? 0);
            const afterQualified = Number(vehicle.afterQualified ?? vehicle.afterCritical ?? 0);
            const vehicleResult = Number(vehicle.unfilled || 0) ? `SHORTFALL ${vehicle.unfilled}` : 'COMPLETE';
            const nameText = names?.length
                ? ` | ${isAssign ? 'assigned' : 'planned'}: ${names.join(', ')}`
                : '';
            const blockText = vehicle.occupiedSeatBlock
                ? ` | ${vehicle.occupiedSeatBlock} required position(s) blocked by existing occupants`
                : '';
            const ruleText = vehicle.ruleLabel ? ` [${vehicle.ruleLabel}]` : '';

            const occupantGapText =
                formatVehicleOccupantTrainingGaps(
                    vehicle
                        .occupantTrainingGaps
                );

            const missingTrainingText =
                occupantGapText
                    ? ` | existing occupants missing: ${occupantGapText}`
                    : '';

            lines.push(
                `  - ${vehicle.name}${ruleText}: before ${beforeQualified}/${target} -> ${afterLabel} ${afterQualified}/${target} ${vehicle.trainingLabel || qualificationLabel} | ${vehicleResult}${nameText}${blockText}${missingTrainingText}`
            );
        });

        return lines.join('\n');
    }

    function renderPersonnelAfterAction(report) {
        PERSONNEL_STATE.lastStationReport = report || null;
        PERSONNEL_STATE.currentStationReport = buildStationAfterActionText(report);
        renderPersonnelAfterActionText(PERSONNEL_STATE.currentStationReport);
    }

    function renderPersonnelAfterActionText(text) {
        const report = getToolElementById('mc-personnel-after-action');
        if (!report) return;

        const wasNearBottom = report.scrollHeight - report.scrollTop - report.clientHeight < 28;
        const oldScrollTop = report.scrollTop;
        report.textContent = String(text || '');
        report.scrollTop = wasNearBottom ? report.scrollHeight : oldScrollTop;
    }

    function buildPersonnelOverallStationBlock(report, isAssign) {
        if (!report) return '';

        const cached = PERSONNEL_REPORT_BLOCK_CACHE.get(report);
        if (cached && cached.isAssign === isAssign) return cached.text;

        const lines = [];
        const stationHeading = Number(report.trainingShortfall || 0) > 0
            ? `⚠ ${report.stationName.toUpperCase()} — ESTIMATED TRAINING SHORTFALL ${report.trainingShortfall} ⚠`
            : report.stationName.toUpperCase();
        lines.push(stationHeading);

        if (report.error) {
            lines.push('  Result: ERROR', `  ERROR: ${report.error}`);
        } else if (report.noTargetVehicles) {
            lines.push('  Result: NO TARGET VEHICLES');
        } else {
            lines.push(
                `  Result: ${getPersonnelReportResult(report)}`,
                `  Final verification: ${isAssign ? (report.afterActionVerified ? 'PASSED' : 'PARTIAL / FAILED') : 'PREVIEW PROJECTION'}`,
                `  Mapped vehicles: ${getPersonnelReportVehicleCount(report)}`,
                ...(
                    Number(report.stationTarget || 0) > 0
                        ? [
                            `  Station target: ${report.stationTarget}`,
                            `  Station target result: ${report.stationTargetMet ? 'PASSED' : 'SHORT'} (${Number(report.stationTargetFulfilled || 0)}/${report.stationTarget})`,
                            `  Additional units required: ${Number(report.stationTargetShortfallUnits || 0)}`
                        ]
                        : []
                ),
                `  Units fully covered: ${Number(report.fulfilledUnits || 0)}`,
                `  Required qualified positions: ${Number(report.required || 0)}`,
                `  Qualified personnel visible: ${Number(report.trained || 0)}`,
                `  Available qualified before: ${Number(report.availableAtScan || 0)}`,
                `  Available qualified after: ${Number(report.availableAtEnd || 0)}`,
                `  Qualified positions before: ${getPersonnelReportInitialFilled(report)}/${Number(report.required || 0)}`,
                `  ${isAssign ? 'Qualified positions after' : 'Projected qualified positions'}: ${getPersonnelReportFinalFilled(report)}/${Number(report.required || 0)}`,
                `  Qualification shortfall estimate: ${Number(report.trainingShortfall || 0)}`,
                `  Missing training by qualification: ${formatPoliceTrainingGapSummary(report.missingTrainingSummary)}`,
                `  ${isAssign ? 'Personnel assigned' : 'Assignments planned'}: ${isAssign ? Number(report.assigned || 0) : Number(report.planned || 0)}`,
                `  Unfilled required positions after action: ${Number(report.assignmentShortfall || 0)}`
            );

            if (report.verificationError) lines.push(`  Verification warning: ${report.verificationError}`);

            if (Array.isArray(report.rules) && report.rules.length > 1) {
                report.rules.forEach(rule => {
                    lines.push(
                        `    Rule: ${rule.label} | vehicles ${rule.vehicleCount} | target ${rule.target} | required ${rule.required} | trained ${rule.trained} | shortfall ${rule.trainingShortfall} | missing ${formatPoliceTrainingGapSummary(rule.trainingGaps)}`
                    );
                });
            }

            report.vehicles.forEach(vehicle => {
                const actionNames = isAssign ? vehicle.assignedNames : vehicle.plannedNames;
                const actionText = actionNames?.length
                    ? ` | ${isAssign ? 'assigned' : 'planned'}: ${actionNames.join(', ')}`
                    : '';
                const seatText = vehicle.occupiedSeatBlock
                    ? ` | ${vehicle.occupiedSeatBlock} required position(s) blocked by existing occupants`
                    : '';
                const afterLabel = isAssign
                    ? (vehicle.verificationStatus === 'final-verified' ? 'final verified' : 'after action')
                    : 'projected';
                const target = Number(vehicle.target || PERSONNEL_TARGET_PER_VEHICLE);
                const beforeQualified = Number(vehicle.beforeQualified ?? vehicle.beforeCritical ?? 0);
                const afterQualified = Number(vehicle.afterQualified ?? vehicle.afterCritical ?? 0);
                const ruleText = vehicle.ruleLabel ? ` [${vehicle.ruleLabel}]` : '';
                const occupantGapText = formatVehicleOccupantTrainingGaps(vehicle.occupantTrainingGaps);
                const missingTrainingText = occupantGapText
                    ? ` | existing occupants missing: ${occupantGapText}`
                    : '';

                lines.push(
                    `    - ${vehicle.name}${ruleText}: before ${beforeQualified}/${target} -> ${afterLabel} ${afterQualified}/${target} | unfilled ${Number(vehicle.unfilled || 0)}${actionText}${seatText}${missingTrainingText}`
                );
            });
        }

        const text = lines.join('\n');
        PERSONNEL_REPORT_BLOCK_CACHE.set(report, { isAssign, text });
        return text;
    }

    function buildAndRenderPersonnelReport() {
        const isAssign = PERSONNEL_STATE.action === 'assign';
        const actionLabel = isAssign ? 'ASSIGN AND VERIFY' : 'PREVIEW ONLY';
        const actionCount = isAssign ? PERSONNEL_STATE.assignedCount : PERSONNEL_STATE.plannedCount;
        const service = getPersonnelServiceDefinition();
        const profile = getPersonnelProfileDefinition();
        const lines = [
            `${service.label.toUpperCase()} — ${profile.label.toUpperCase()} ${isAssign ? 'PERSONNEL AFTER-ACTION REPORT' : 'PERSONNEL PREVIEW REPORT'}`,
            `Action: ${actionLabel}`,
            `Generated: ${new Date().toLocaleString('en-GB')}`,
            `Rule: ${profile.requirement}`,
            `${isPersonnelPerStationTargetMode() ? 'Units requested at every station' : 'Units requested'}: ${isPersonnelPerStationTargetMode() ? PERSONNEL_STATE.unitsRequired : 'ALL MATCHING UNITS'}`,
            `${isPersonnelPerStationTargetMode() ? 'Station targets' : 'Units fulfilled'}: ${formatPersonnelUnitsFulfilled()}`,
            ''
        ];

        const trainingShortfallReports = getPersonnelTrainingShortfallReports();

        if (trainingShortfallReports.length) {
            lines.push(`⚠ QUALIFICATION SHORTFALL STATIONS (${trainingShortfallReports.length}) ⚠`);
            trainingShortfallReports.forEach(report => {
                lines.push(
                    `  ⚠ ${report.stationName.toUpperCase()}: ESTIMATED SHORTFALL ${report.trainingShortfall} | required ${report.required} | qualified visible ${report.trained} | missing ${formatPoliceTrainingGapSummary(report.missingTrainingSummary)}`
                );
            });
            lines.push('');
        } else if (PERSONNEL_STATE.reports.some(report => !report.error && !report.noTargetVehicles)) {
            lines.push('QUALIFICATION SHORTFALL STATIONS: NONE', '');
        }

        PERSONNEL_STATE.reports.forEach(report => {
            lines.push(buildPersonnelOverallStationBlock(report, isAssign), '');
        });

        lines.push(
            'TOTALS',
            `  Stations completed: ${PERSONNEL_STATE.completedStations}`,
            `  Stations skipped: ${PERSONNEL_STATE.skippedStations}`,
            `  Vehicles checked: ${PERSONNEL_STATE.checkedVehicles}`,
            `  ${isPersonnelPerStationTargetMode() ? 'Units required at every station' : 'Units requested'}: ${isPersonnelPerStationTargetMode() ? PERSONNEL_STATE.unitsRequired : 'ALL'}`,
            `  ${isPersonnelPerStationTargetMode() ? 'Station targets' : 'Units fulfilled'}: ${formatPersonnelUnitsFulfilled()}`,
            ...(
                isPersonnelPerStationTargetMode()
                    ? [
                        `  Stations meeting target: ${PERSONNEL_STATE.stationsTargetMet}`,
                        `  Stations below target: ${PERSONNEL_STATE.stationsTargetShort}`
                    ]
                    : []
            ),
            `  ${isAssign ? 'Personnel assigned' : 'Assignments planned'}: ${actionCount}`,
            `  Qualification shortfall estimate: ${PERSONNEL_STATE.trainingShortfall}`,
            `  Unfilled required positions after action: ${PERSONNEL_STATE.assignmentShortfall}`
        );

        PERSONNEL_STATE.currentReport = lines.join('\n');
        renderPersonnelReport(PERSONNEL_STATE.currentReport);
        updatePersonnelTrainingShortfallHighlights();
    }

    function getPersonnelTrainingShortfallReports() {
        if (PERSONNEL_SHORTFALL_CACHE_SIZE === PERSONNEL_STATE.reports.length) {
            return PERSONNEL_SHORTFALL_CACHE;
        }

        PERSONNEL_SHORTFALL_CACHE = PERSONNEL_STATE.reports
            .filter(report => !report?.error && Number(report?.trainingShortfall || 0) > 0)
            .slice()
            .sort((left, right) => {
                const shortfallDifference = Number(right.trainingShortfall || 0) - Number(left.trainingShortfall || 0);
                if (shortfallDifference) return shortfallDifference;
                return String(left.stationName || '').localeCompare(String(right.stationName || ''), 'en-GB', { numeric: true });
            });
        PERSONNEL_SHORTFALL_CACHE_SIZE = PERSONNEL_STATE.reports.length;
        return PERSONNEL_SHORTFALL_CACHE;
    }

    function updatePersonnelTrainingShortfallHighlights() {
        const section = getToolElementById('mc-personnel-training-shortfall-section');
        const count = getToolElementById('mc-personnel-training-shortfall-station-count');
        const list = getToolElementById('mc-personnel-training-shortfall-list');
        const shortages = getPersonnelTrainingShortfallReports();

        if (section && count && list) {
            count.textContent = String(shortages.length);
            section.hidden = shortages.length === 0;
            const fragment = document.createDocumentFragment();

            shortages.forEach(report => {
                const row = document.createElement('div');
                row.className = 'mc-personnel-training-shortfall-row';

                const name = document.createElement('span');
                name.className = 'mc-personnel-training-shortfall-name';
                name.textContent = report.stationName || 'Unknown station';

                const value = document.createElement('span');
                value.className = 'mc-personnel-training-shortfall-value';
                value.textContent = `Need ${report.trainingShortfall}`;

                row.append(name, value);
                fragment.appendChild(row);
            });

            list.replaceChildren(fragment);
        }

        const shortageByHref = new Map(
            shortages
                .filter(report => report.stationHref)
                .map(report => [String(report.stationHref), Number(report.trainingShortfall || 0)])
        );

        PERSONNEL_STATE.filteredStations.forEach(station => {
            const option = PERSONNEL_START_OPTION_BY_HREF.get(String(station.href));
            if (!option) return;

            const stationShortfall = shortageByHref.get(String(station.href)) || 0;
            option.textContent = stationShortfall > 0
                ? `⚠ ${station.displayName} — NEEDS ${stationShortfall} TRAINING`
                : `${station.displayName} [building type ${station.buildingTypeId ?? '?'}]`;
        });

        for (const link of PERSONNEL_HIGHLIGHTED_STATION_LINKS) {
            link.classList.remove('mc-personnel-training-shortfall-station');
            link.removeAttribute('data-mc-personnel-training-shortfall');
            if (link.title?.includes('qualification shortfall:')) link.removeAttribute('title');
        }
        PERSONNEL_HIGHLIGHTED_STATION_LINKS.clear();

        shortages.forEach(report => {
            const stationLink = PERSONNEL_STATION_LINK_BY_HREF.get(String(report.stationHref || ''));
            if (!stationLink?.isConnected) return;

            stationLink.classList.add('mc-personnel-training-shortfall-station');
            stationLink.dataset.mcPersonnelTrainingShortfall = String(report.trainingShortfall);
            stationLink.title = `${getPersonnelProfileDefinition().label} qualification shortfall: ${report.trainingShortfall} additional qualified staff estimated`;
            PERSONNEL_HIGHLIGHTED_STATION_LINKS.add(stationLink);
        });
    }

    function renderPersonnelReport(text) {
        const report = getToolElementById('mc-personnel-report');
        if (!report) return;

        const wasNearBottom = report.scrollHeight - report.scrollTop - report.clientHeight < 28;
        const oldScrollTop = report.scrollTop;
        report.textContent = String(text || '');
        report.scrollTop = wasNearBottom ? report.scrollHeight : oldScrollTop;
    }

    async function copyTextToClipboard(text, successMessage) {
        const value = String(text || '');

        try {
            await navigator.clipboard.writeText(value);
            personnelLog(successMessage, 'done');
        } catch (_error) {
            const textarea = document.createElement('textarea');
            textarea.value = value;
            textarea.style.position = 'fixed';
            textarea.style.left = '-9999px';
            document.body.appendChild(textarea);
            textarea.select();
            const copied = document.execCommand('copy');
            textarea.remove();
            personnelLog(copied ? successMessage : 'Clipboard copy failed. Select the report text manually.', copied ? 'done' : 'error');
        }
    }

    async function copyPersonnelReport() {
        if (!PERSONNEL_STATE.currentReport) buildAndRenderPersonnelReport();
        await copyTextToClipboard(PERSONNEL_STATE.currentReport || '', 'Overall report copied to clipboard.');
    }

    async function copyPersonnelStationReport() {
        if (!PERSONNEL_STATE.currentStationReport && PERSONNEL_STATE.lastStationReport) {
            renderPersonnelAfterAction(PERSONNEL_STATE.lastStationReport);
        }

        if (!PERSONNEL_STATE.currentStationReport) {
            personnelLog('No completed station report is available to copy.', 'error');
            return;
        }

        await copyTextToClipboard(PERSONNEL_STATE.currentStationReport, 'Station after-action report copied to clipboard.');
    }

    function scrollPersonnelTo(sectionId) {
        const body = document.querySelector('#mc-namer-body');
        const section = document.getElementById(sectionId);
        if (!body || !section) return;

        const bodyRect = body.getBoundingClientRect();
        const sectionRect = section.getBoundingClientRect();
        const targetTop = body.scrollTop + sectionRect.top - bodyRect.top - 38;
        body.scrollTo({ top: Math.max(0, targetTop), behavior: 'smooth' });
    }

    async function waitIfPersonnelPaused() {
        while (PERSONNEL_STATE.paused && !PERSONNEL_STATE.stopped) {
            await sleep(250);
        }
    }

    function updatePersonnelCounters() {
        setPersonnelUiValue('completed', PERSONNEL_STATE.completedStations);
        setPersonnelUiValue('vehicles', PERSONNEL_STATE.checkedVehicles);
        setPersonnelUiValue('unitsFulfilled', formatPersonnelUnitsFulfilled());
        setPersonnelUiValue('assigned', PERSONNEL_STATE.action === 'assign' ? PERSONNEL_STATE.assignedCount : PERSONNEL_STATE.plannedCount);
        setPersonnelUiValue('trainingShortfall', PERSONNEL_STATE.trainingShortfall);
        setPersonnelUiValue('assignmentShortfall', PERSONNEL_STATE.assignmentShortfall);
    }

    function setPersonnelUiValue(field, value) {
        const map = {
            status: 'mc-personnel-status',
            current: 'mc-personnel-current',
            vehicle: 'mc-personnel-vehicle',
            progress: 'mc-personnel-progress',
            completed: 'mc-personnel-completed',
            vehicles: 'mc-personnel-vehicles',
            unitsFulfilled: 'mc-personnel-units-fulfilled',
            assigned: 'mc-personnel-assigned',
            trainingShortfall: 'mc-personnel-training-shortfall',
            assignmentShortfall: 'mc-personnel-assignment-shortfall'
        };

        const el = getToolElementById(map[field]);
        if (el) el.textContent = String(value);
    }

    function togglePersonnelDebug() {
        PERSONNEL_STATE.debug = !PERSONNEL_STATE.debug;
        document.querySelector('#mc-personnel-debug').textContent = PERSONNEL_STATE.debug ? 'Debug: ON' : 'Debug: OFF';
        personnelLog(`Debug ${PERSONNEL_STATE.debug ? 'enabled' : 'disabled'}.`, 'debug');
    }

    function clearPersonnelLog() {
        clearBoundedToolLog(getToolElementById('mc-personnel-log'));
    }

    function personnelLog(message, type = 'info') {
        const logBox = getToolElementById('mc-personnel-log');
        if (!logBox) return;

        const line = document.createElement('div');
        line.className = `mc-log-${type}`;
        line.textContent = message;
        appendBoundedToolLog(logBox, line);
    }

    function personnelDebug(message) {
        if (!PERSONNEL_STATE.debug) return;
        personnelLog(`[DEBUG] ${message}`, 'debug');
    }

    function makePanelDraggable(panel, handle) {
        let dragging = false;
        let activePointerId = null;
        let startX = 0;
        let startY = 0;
        let startLeft = 0;
        let startTop = 0;

        const endDrag = event => {
            if (
                activePointerId != null
                && event?.pointerId != null
                && event.pointerId !== activePointerId
            ) {
                return;
            }

            dragging = false;
            if (
                activePointerId != null
                && handle.hasPointerCapture?.(activePointerId)
            ) {
                try {
                    handle.releasePointerCapture(activePointerId);
                } catch (_error) {}
            }
            activePointerId = null;
            clampToolPanelToViewport(panel);
        };

        const onPointerDown = event => {
            if (event.target.closest('#mc-namer-collapse')) return;
            if (event.button != null && event.button !== 0) return;

            const rect = panel.getBoundingClientRect();
            const bounds = getToolViewportBounds();
            dragging = true;
            activePointerId = event.pointerId;
            startX = event.clientX;
            startY = event.clientY;
            startLeft = rect.left;
            startTop = rect.top;

            panel.style.width = `${Math.min(rect.width, Math.max(260, bounds.width - 16))}px`;
            panel.style.left = `${startLeft}px`;
            panel.style.top = `${startTop}px`;
            panel.style.right = 'auto';

            try {
                handle.setPointerCapture?.(event.pointerId);
            } catch (_error) {}

            event.preventDefault();
        };

        const onPointerMove = event => {
            if (
                !dragging
                || (
                    activePointerId != null
                    && event.pointerId !== activePointerId
                )
            ) {
                return;
            }

            const bounds = getToolViewportBounds();
            const rect = panel.getBoundingClientRect();
            const maximumLeft = Math.max(
                bounds.left,
                bounds.right - rect.width
            );
            const maximumTop = Math.max(
                bounds.top,
                bounds.bottom - rect.height
            );
            const nextLeft = Math.min(
                maximumLeft,
                Math.max(
                    bounds.left,
                    startLeft + event.clientX - startX
                )
            );
            const nextTop = Math.min(
                maximumTop,
                Math.max(
                    bounds.top,
                    startTop + event.clientY - startY
                )
            );

            panel.style.left = `${nextLeft}px`;
            panel.style.top = `${nextTop}px`;
            event.preventDefault();
        };

        handle.addEventListener('pointerdown', onPointerDown);
        handle.addEventListener('pointermove', onPointerMove);
        handle.addEventListener('pointerup', endDrag);
        handle.addEventListener('pointercancel', endDrag);

        registerToolLifecycleCleanup(() => {
            dragging = false;
            activePointerId = null;
            handle.removeEventListener('pointerdown', onPointerDown);
            handle.removeEventListener('pointermove', onPointerMove);
            handle.removeEventListener('pointerup', endDrag);
            handle.removeEventListener('pointercancel', endDrag);
        });
    }


    function cleanText(text) {
        return String(text || '')
            .replace(/🚑|🚒|🚓|🚁|🚤|🏥|🔥|🚨|☢️|🤿|🦺|🎖️|🚔|🚛|🧯|🚐|🚚|🚙|🚗|🚜|🚢|🛟|🎯|🏣|🧑‍🚒|🚌|🚒🪜|🚔🔫|🚔🥅|🚔🐎|⚠️|🛻|🟤|🛥️|✈️|🪜|📡|🛠️|🌊|🟡|🏔️|🐕|💣|❤️|💧|👷|🫧|1️⃣|2️⃣/g, '')
            .replace(/\s+/g, ' ')
            .trim();
    }

    function createCallsignBase(stationName) {
        return cleanText(stationName)
            .replace(/\s+AO Station$/i, '')
            .replace(/\s+Ambulance Station$/i, '')
            .replace(/\s+Fire Station$/i, '')
            .replace(/\s+Police Station$/i, '')
            .replace(/\s+Station$/i, '')
            .trim();
    }

    function detectStationType(name) {
        const n = cleanText(name).toUpperCase();

        if (n.includes('AIRMED') || n.includes('AIR AMB')) return 'AIR';
        if (n.includes('AIRPORT')) return 'AIRFIELD';
        if (n.includes('BOMB') || n.includes('EOD')) return 'EOD';
        if (n.includes('RECOVERY')) return 'RECOVERY';
        if (n.includes('SAR')) return 'SAR';
        if (n.includes('RNLI') || n.includes('-LB') || n.includes('LIFEBOAT')) return 'RNLI';
        if (n.includes('-CG') || n.includes('COASTGUARD')) return 'COASTGUARD';
        if (n.includes('-PS') || n.includes('POLICE')) return 'POLICE';
        if (n.includes('-AS') || n.includes('AO STATION') || n.includes('AMBULANCE')) return 'AMBULANCE';
        if (n.includes('-FS') || n.includes('FIRE')) return 'FIRE';

        return 'OTHER';
    }

    function getVehicleIdFromHref(href) {
        const match = String(href || '').match(/\/vehicles\/(\d+)/);
        return match ? match[1] : '';
    }

    function makeVehicleName(station, vehicleType, count) {
        const info = VEHICLE_INFO[vehicleType];
        if (!info) return null;
        return `${info.icon ? info.icon + ' ' : ''}${station.callsignBase}-${info.code}-${count}`;
    }

    function navigateUnitIframe(iframe, href) {
        if (!iframe || !href) return false;

        try {
            iframe.contentWindow.location.replace(href);
            return true;
        } catch (_error) {
            try {
                iframe.setAttribute('src', href);
                return true;
            } catch (_fallbackError) {
                return false;
            }
        }
    }

    function releaseUnitIframeDocument(iframe) {
        if (!iframe) return;

        try {
            iframe.contentWindow.location.replace('about:blank');
        } catch (_error) {
            try {
                iframe.setAttribute('src', 'about:blank');
            } catch (_fallbackError) {}
        }
    }

    function getUnitModalCloseButton(iframe) {
        const modal = iframe?.closest?.(
            '.vm--modal, [role="dialog"], .lightbox, .modal'
        );

        const scoped = modal?.querySelector?.(
            'span.lightbox-close, button.lightbox-close, .vm--modal-close, button.close'
        );

        if (scoped) return scoped;

        const candidates = [
            ...document.querySelectorAll(
                'span.lightbox-close, button.lightbox-close, .vm--modal-close, button.close'
            )
        ];

        return candidates.reverse().find(button => {
            return button.offsetParent !== null;
        }) || candidates[0] || null;
    }

    function getUnitClassOptionsForStationType(stationType) {
        const selectedStationType = String(stationType || 'ALL');
        const configuredTypeIds =
            UNIT_CLASS_TYPE_IDS_BY_STATION_TYPE[selectedStationType];

        const typeIds =
            Array.isArray(configuredTypeIds)
                ? configuredTypeIds
                : Object.keys(TYPE_ID_TO_VEHICLE_TYPE);

        const byVehicleType = new Map();

        typeIds.forEach(vehicleTypeId => {
            const vehicleType =
                TYPE_ID_TO_VEHICLE_TYPE[String(vehicleTypeId)] || '';
            const info = VEHICLE_INFO[vehicleType];

            if (!vehicleType || !info || byVehicleType.has(vehicleType)) {
                return;
            }

            byVehicleType.set(vehicleType, {
                vehicleType,
                vehicleTypeId: String(vehicleTypeId),
                label:
                    `${info.icon ? `${info.icon} ` : ''}${vehicleType} (${info.code})`
            });
        });

        return Array.from(byVehicleType.values()).sort((left, right) => {
            return left.vehicleType.localeCompare(
                right.vehicleType,
                'en-GB',
                {
                    numeric: true,
                    sensitivity: 'base'
                }
            );
        });
    }

    function getSelectedUnitClass() {
        return document.querySelector('#mc-namer-unit-class')?.value ||
            STATE.selectedUnitClass ||
            UNIT_CLASS_ALL;
    }

    function getUnitClassDisplayLabel(value = getSelectedUnitClass()) {
        const selected = String(value || UNIT_CLASS_ALL);
        if (selected === UNIT_CLASS_ALL) return 'All classes';

        const info = VEHICLE_INFO[selected];
        return info
            ? `${selected} (${info.code})`
            : selected;
    }

    function populateUnitClassDropdown() {
        const select = document.querySelector('#mc-namer-unit-class');
        if (!select) return;

        const selectedStationType =
            document.querySelector('#mc-namer-station-type')?.value ||
            'ALL';

        const previous =
            select.value ||
            STATE.selectedUnitClass ||
            UNIT_CLASS_ALL;

        const options =
            getUnitClassOptionsForStationType(selectedStationType);

        select.innerHTML = '';

        const allOption = document.createElement('option');
        allOption.value = UNIT_CLASS_ALL;
        allOption.textContent = 'All classes';
        select.appendChild(allOption);

        options.forEach(item => {
            const option = document.createElement('option');
            option.value = item.vehicleType;
            option.textContent = item.label;
            option.dataset.vehicleTypeId = item.vehicleTypeId;
            select.appendChild(option);
        });

        const available = new Set([
            UNIT_CLASS_ALL,
            ...options.map(item => item.vehicleType)
        ]);

        select.value = available.has(previous)
            ? previous
            : UNIT_CLASS_ALL;

        STATE.selectedUnitClass = select.value;
        select.title =
            `${options.length} naming classes available for ` +
            `${STATION_TYPES[selectedStationType] || selectedStationType}`;
    }

    function handleUnitStationTypeChange() {
        populateUnitClassDropdown();
        populateStartDropdown();
    }

    function handleUnitClassChange() {
        STATE.selectedUnitClass = getSelectedUnitClass();
        populateStartDropdown();
        setStatus('Class filter updated');
        log(`Unit class: ${getUnitClassDisplayLabel()}`, 'info');
    }

    function vehicleMatchesSelectedUnitClass(vehicle) {
        const selected =
            STATE.selectedUnitClass ||
            getSelectedUnitClass();

        return (
            selected === UNIT_CLASS_ALL ||
            vehicle?.vehicleType === selected
        );
    }

    function refreshStations() {
        if (PERSONNEL_STATE.running) {
            log('Personnel Assignment is currently running. Stop it before refreshing Unit Naming.', 'error');
            return;
        }

        if (STATE.running) {
            log('Cannot refresh while running. Stop first.', 'error');
            return;
        }

        populateUnitClassDropdown();
        STATE.selectedUnitClass = getSelectedUnitClass();
        setStatus('Refreshing stations...');
        log('Refreshing station list...', 'info');
        log(`Unit class filter: ${getUnitClassDisplayLabel()}`, 'info');

        const stationEntries = getStationOverviewEntries();

        STATE.stations = stationEntries.map((entry, index) => ({
            index,
            href: entry.href,
            displayName: entry.displayName,
            callsignBase: createCallsignBase(entry.displayName),
            stationType:
                STATION_BUILDING_TYPE_INFO[entry.buildingTypeId]?.stationType ||
                detectStationType(entry.displayName)
        }));

        populateStartDropdown();

        setStatus('Ready');
        setProgress(0, STATE.filteredStations.length);

        log(`Stations found: ${STATE.stations.length}`, 'info');
        log(`Matching filter: ${STATE.filteredStations.length}`, 'info');

        if (STATE.filteredStations.length) {
            log(`First match: ${STATE.filteredStations[0].displayName}`, 'info');
            log(`Last match : ${STATE.filteredStations[STATE.filteredStations.length - 1].displayName}`, 'info');
        }
    }

    function populateStartDropdown() {
        const select = document.querySelector('#mc-namer-startfrom');
        if (!select) return;

        const selectedType = document.querySelector('#mc-namer-station-type')?.value || 'ALL';

        STATE.filteredStations = STATE.stations.filter(station => {
            return selectedType === 'ALL' || station.stationType === selectedType;
        });

        select.innerHTML = '';

        if (!STATE.filteredStations.length) {
            select.innerHTML = `<option value="">No matching stations found</option>`;
            setProgress(0, 0);
            return;
        }

        const firstOption = document.createElement('option');
        firstOption.value = STATE.filteredStations[0].href;
        firstOption.textContent = 'Start from first matching station';
        select.appendChild(firstOption);

        STATE.filteredStations.forEach(station => {
            const option = document.createElement('option');
            option.value = station.href;
            option.textContent = `${station.displayName} [${STATION_TYPES[station.stationType] || station.stationType}]`;
            select.appendChild(option);
        });

        setProgress(0, STATE.filteredStations.length);
    }

    function startRun() {
        if (PERSONNEL_STATE.running) {
            log('Personnel Assignment is currently running. Stop it before starting Unit Naming.', 'error');
            return;
        }

        if (STATION_STATE.running) {
            log('Station Naming is currently running. Stop it before starting Unit Naming.', 'error');
            return;
        }

        if (STATE.running) {
            log('Already running.', 'debug');
            return;
        }

        if (STATE.activeIframe) {
            releaseUnitIframeDocument(STATE.activeIframe);
            STATE.activeIframe = null;
        }

        if (!STATE.filteredStations.length) {
            log('No matching stations loaded. Press Refresh Stations first.', 'error');
            return;
        }

        const selectedHref = document.querySelector('#mc-namer-startfrom').value;
        const startIndex = STATE.filteredStations.findIndex(station => station.href === selectedHref);

        if (startIndex < 0) {
            log(`Selected start station not found: ${selectedHref}`, 'error');
            return;
        }

        STATE.mode = document.querySelector('#mc-namer-mode')?.value || 'all';
        STATE.selectedUnitClass = getSelectedUnitClass();
        STATE.running = true;
        STATE.paused = false;
        STATE.stopped = false;
        STATE.stationIndex = startIndex;
        STATE.renamedCount = 0;
        STATE.skippedCount = 0;
        const runId = ++STATE.runId;

        updateCounters();
        document.querySelector('#mc-namer-pause').textContent = 'Pause';

        log(`Mode: ${STATE.mode === 'single' ? 'Selected station only' : 'All matching stations'}`, 'info');
        log(`Station type: ${STATION_TYPES[document.querySelector('#mc-namer-station-type').value]}`, 'info');
        log(`Unit class: ${getUnitClassDisplayLabel(STATE.selectedUnitClass)}`, 'info');
        log(`Starting from: ${STATE.filteredStations[startIndex].displayName}`, 'info');

        processStations(runId).catch(error => {
            if (runId !== STATE.runId) return;
            log(`Unit Naming stopped after an unexpected error: ${error?.message || error}`, 'error');
            debug(error?.stack || String(error));
            STATE.stopped = true;
            setStatus('Error');
        });
    }

    function togglePause() {
        if (!STATE.running) return;

        STATE.paused = !STATE.paused;
        document.querySelector('#mc-namer-pause').textContent = STATE.paused ? 'Resume' : 'Pause';
        setStatus(STATE.paused ? 'Paused' : 'Running');
        log(STATE.paused ? 'Paused.' : 'Resumed.', 'debug');
    }

    function stopRun() {
        if (!STATE.running) return;

        STATE.stopped = true;
        STATE.paused = false;
        document.querySelector('#mc-namer-pause').textContent = 'Pause';
        setStatus('Stopping...');
        log('Stop requested. The current safe step will finish, then the run will close.', 'error');
    }

    function toggleDebug() {
        STATE.debug = !STATE.debug;

        document.querySelector('#mc-namer-debug').textContent = STATE.debug ? 'Debug: ON' : 'Debug: OFF';
        log(`Debug ${STATE.debug ? 'enabled' : 'disabled'}.`, 'debug');
    }

    function clearLog() {
        clearBoundedToolLog(getToolElementById('mc-namer-log'));
    }

    async function processStations(runId) {
        try {
            while (STATE.stationIndex < STATE.filteredStations.length) {
                if (STATE.stopped || runId !== STATE.runId) break;

                await waitIfPaused(runId);
                if (STATE.stopped || runId !== STATE.runId) break;

                const station = STATE.filteredStations[STATE.stationIndex];

                setStatus('Opening station');
                setStation(station.displayName);
                setVehicle('None');
                setProgress(STATE.stationIndex, STATE.filteredStations.length);

                log(`Station: ${station.displayName}`, 'station');

                const stationEntry = findStationOverviewEntry(station.href);
                const stationLink = stationEntry?.link || null;

                if (!stationLink) {
                    log(`Station link not found, skipped: ${station.displayName}`, 'error');
                    STATE.stationIndex++;
                    continue;
                }

                const iframe = await openStationWorkflowIframe(
                    stationEntry,
                    'unit-naming',
                    waitForStationIframe
                );

                if (iframe) {
                    STATE.activeIframe = iframe;
                }

                if (!iframe) {
                    log(`Station iframe not found, skipped: ${station.displayName}`, 'error');
                    STATE.skippedCount++;
                    updateCounters();
                    await closeStationModal(iframe);
                    STATE.stationIndex++;
                    continue;
                }

                const vehicleTableReady = await waitForVehicleTable(iframe);

                if (!vehicleTableReady) {
                    log(`Vehicle table did not load, skipped: ${station.displayName}`, 'error');
                    STATE.skippedCount++;
                    updateCounters();
                    await closeStationModal(iframe);
                    STATE.stationIndex++;
                    continue;
                }

                await processStationVehicleQueue(iframe, station);
                await closeStationModal(iframe);

                if (STATE.mode === 'single') {
                    log('Single station mode complete.', 'done');
                    break;
                }

                STATE.stationIndex++;
            }
        } finally {
            if (STATE.activeIframe) {
                await closeStationModal(STATE.activeIframe);
            }

            if (runId !== STATE.runId) return;

            STATE.running = false;
            STATE.paused = false;
            document.querySelector('#mc-namer-pause').textContent = 'Pause';

            if (STATE.stopped) {
                setStatus('Stopped');
                log(`Stopped. Renamed ${STATE.renamedCount}. Skipped ${STATE.skippedCount}.`, 'error');
            } else {
                setStatus('Finished');
                setStation('None');
                setVehicle('None');
                setProgress(
                    STATE.mode === 'single' ? 1 : STATE.filteredStations.length,
                    STATE.mode === 'single' ? 1 : STATE.filteredStations.length
                );
                log(`Finished. Renamed ${STATE.renamedCount}. Skipped ${STATE.skippedCount}.`, 'done');
            }
        }
    }

    async function waitForStationIframe(stationHref, preferredIframe = null, maximumAttempts = 80) {
        const expectedHref = String(stationHref || '');
        const expectedBuildingId = getBuildingIdFromHref(expectedHref);

        for (let i = 0; i < maximumAttempts; i++) {
            if (STATE.stopped) return null;

            const candidates = [
                preferredIframe,
                ...document.querySelectorAll(
                    'iframe.lightbox_iframe, iframe#lssmv4-redesign-lightbox-iframe, ' +
                    '.vm--modal iframe[src*="/buildings/"], ' +
                    'iframe.mc-namer-managed-station-iframe'
                )
            ].filter(Boolean);

            for (const iframe of candidates.reverse()) {
                try {
                    const doc = iframe.contentDocument;
                    if (!doc) continue;

                    const currentPath = iframe.contentWindow?.location?.pathname || '';
                    const sourcePath = iframe.getAttribute('src') || '';
                    const currentBuildingId = getBuildingIdFromHref(currentPath || sourcePath);

                    const exactStationMatch = Boolean(
                        expectedHref && (
                            currentPath.startsWith(expectedHref) ||
                            sourcePath.startsWith(expectedHref) ||
                            sourcePath.includes(expectedHref)
                        )
                    );

                    const buildingIdMatch = Boolean(
                        expectedBuildingId && currentBuildingId === expectedBuildingId
                    );

                    const documentMatch = Boolean(
                        expectedHref && (
                            doc.querySelector(`#vehicle_table`) ||
                            doc.querySelector(`a[href="${expectedHref}/edit"]`) ||
                            doc.querySelector(`a[href="${expectedHref}/move"]`) ||
                            doc.querySelector(`form[action="${expectedHref}"]`)
                        )
                    );

                    if (exactStationMatch || buildingIdMatch || documentMatch) {
                        debug(`Station iframe found: ${currentPath || sourcePath || 'unknown path'}`);
                        return iframe;
                    }
                } catch (error) {
                    debug(`Station iframe access retry: ${error?.message || error}`);
                }
            }

            await sleep(250);
        }

        return null;
    }

    async function waitForVehicleTable(iframe) {
        for (let i = 0; i < 80; i++) {
            if (STATE.stopped) return false;

            try {
                const doc = iframe.contentDocument;
                if (doc && doc.querySelector('#vehicle_table tbody tr')) {
                    await sleep(300);
                    return true;
                }
            } catch (e) {}

            await sleep(250);
        }
        return false;
    }

    async function waitForEditPage(iframe) {
        for (let i = 0; i < 80; i++) {
            if (STATE.stopped) return false;

            try {
                const doc = iframe.contentDocument;
                if (doc && doc.querySelector('#vehicle_caption')) {
                    await sleep(300);
                    return true;
                }
            } catch (e) {}

            await sleep(250);
        }
        return false;
    }

    function getVehicleQueueFromTable(doc) {
        return [...doc.querySelectorAll('#vehicle_table tbody tr')]
            .map((row, index) => {
                const img = row.querySelector('img[vehicle_type_id]');
                const vehicleTypeId = img?.getAttribute('vehicle_type_id') || '';
                const vehicleType = TYPE_ID_TO_VEHICLE_TYPE[vehicleTypeId] || '';

                const allLinks = [...row.querySelectorAll('a[href^="/vehicles/"]')];

                const editLink = allLinks.find(a => {
                    const href = a.getAttribute('href') || '';
                    return href.endsWith('/edit');
                });

                const vehicleLink = allLinks.find(a => {
                    const href = a.getAttribute('href') || '';
                    return !href.endsWith('/edit') && !href.includes('/zuweisung');
                });

                const vehicleHref = vehicleLink?.getAttribute('href') || '';
                const editHref = editLink?.getAttribute('href') || '';
                const vehicleId = getVehicleIdFromHref(editHref || vehicleHref);
                const currentName = cleanText(vehicleLink?.textContent || '');

                return {
                    tableIndex: index,
                    vehicleId,
                    vehicleTypeId,
                    vehicleType,
                    currentName,
                    vehicleHref,
                    editHref
                };
            })
            .filter(v => v.editHref && v.vehicleId)
            .filter(vehicleMatchesSelectedUnitClass);
    }

    async function processStationVehicleQueue(iframe, station) {
        setStatus('Building vehicle queue');

        // Build a lightweight string-only queue and release the station document
        // before the first navigation. Holding the original document across every
        // awaited edit page kept the full station DOM alive for the whole run.
        const queue = getVehicleQueueFromTable(
            iframe.contentDocument
        );

        debug(`Vehicle queue built for ${station.displayName}: ${queue.length}`);

        if (!queue.length) {
            log(`No ${getUnitClassDisplayLabel(STATE.selectedUnitClass)} vehicles found in ${station.displayName}.`, 'debug');
            return;
        }

        const counts = {};

        for (const item of queue) {
            if (STATE.stopped) return;

            await waitIfPaused();
            if (STATE.stopped) return;

            if (!item.vehicleType) {
                log(`Unknown vehicle_type_id skipped: ${item.vehicleTypeId} | ${item.editHref}`, 'error');
                STATE.skippedCount++;
                updateCounters();
                continue;
            }

            const info = VEHICLE_INFO[item.vehicleType];

            if (!info) {
                log(`No naming rule skipped: "${item.vehicleType}"`, 'error');
                STATE.skippedCount++;
                updateCounters();
                continue;
            }

            counts[item.vehicleType] = (counts[item.vehicleType] || 0) + 1;

            const newName = makeVehicleName(
                station,
                item.vehicleType,
                counts[item.vehicleType]
            );

            setStatus('Opening edit page');
            setVehicle(item.editHref);

            // Replace rather than append to the iframe history. This prevents a
            // long rename run from retaining one browsing-history document for
            // every vehicle edit page.
            if (!navigateUnitIframe(iframe, item.editHref)) {
                log(`Could not navigate to vehicle edit page: ${item.editHref}`, 'error');
                STATE.skippedCount++;
                updateCounters();
                continue;
            }

            const editPageReady = await waitForEditPage(iframe);

            if (!editPageReady) {
                log(`Vehicle edit page did not load: ${item.editHref}`, 'error');
                STATE.skippedCount++;
                updateCounters();
                continue;
            }

            let editDoc = iframe.contentDocument;
            let captionInput = editDoc?.querySelector('#vehicle_caption') || null;
            let saveBtn = editDoc?.querySelector(
                'input[type="submit"][value="Save"], button[type="submit"]'
            ) || null;

            if (!captionInput || !saveBtn) {
                log(`Caption or Save missing: ${item.editHref}`, 'error');
                STATE.skippedCount++;
                updateCounters();
                editDoc = null;
                captionInput = null;
                saveBtn = null;
                continue;
            }

            const before = captionInput.value;

            setStatus('Saving vehicle');
            setVehicle(newName);

            captionInput.value = newName;
            captionInput.dispatchEvent(new Event('input', { bubbles: true }));
            captionInput.dispatchEvent(new Event('change', { bubbles: true }));

            log(`BEFORE: ${before}`, 'before');
            log(`AFTER : ${newName}`, 'after');

            saveBtn.click();

            STATE.renamedCount++;
            updateCounters();

            // Do not retain the completed edit document or its form controls
            // during the post-save wait.
            editDoc = null;
            captionInput = null;
            saveBtn = null;

            await sleep(700);
        }

        navigateUnitIframe(iframe, station.href);
        await waitForVehicleTable(iframe);
        await sleep(300);
    }

    async function closeStationModal(iframe = STATE.activeIframe) {
        setStatus('Closing station');

        const activeIframe = iframe || STATE.activeIframe;
        if (STATE.activeIframe === activeIframe) {
            STATE.activeIframe = null;
        }

        if (removeManagedStationIframe(activeIframe)) {
            await sleep(50);
            return;
        }

        const closeBtn = getUnitModalCloseButton(activeIframe);

        if (closeBtn) {
            closeBtn.click();

            // Give the framework a short opportunity to detach or hide the
            // correct modal before its iframe document is cleared.
            for (let attempt = 0; attempt < 15; attempt++) {
                const modal = activeIframe?.closest?.(
                    '.vm--modal, [role="dialog"], .lightbox, .modal'
                );

                if (
                    !activeIframe?.isConnected ||
                    (modal && modal.offsetParent === null)
                ) {
                    break;
                }

                await sleep(100);
            }
        } else {
            log('Close button not found.', 'error');
        }

        // MissionChief may hide and reuse the modal instead of removing it.
        // Blank the associated iframe so its station/edit documents and history
        // become collectible before the next station is opened.
        releaseUnitIframeDocument(activeIframe);
        await sleep(150);
    }

    async function waitIfPaused(runId = STATE.runId) {
        while (STATE.paused && !STATE.stopped && runId === STATE.runId) {
            await sleep(300);
        }
    }

    function setStatus(text) {
        const el = getToolElementById('mc-namer-status');
        if (el) el.textContent = text;
    }

    function setStation(text) {
        const el = getToolElementById('mc-namer-station');
        if (el) el.textContent = text;
    }

    function setVehicle(text) {
        const el = getToolElementById('mc-namer-vehicle');
        if (el) el.textContent = text;
    }

    function setProgress(done, total) {
        const el = getToolElementById('mc-namer-progress');
        if (el) el.textContent = `${done} / ${total}`;
    }

    function updateCounters() {
        const renamed = getToolElementById('mc-namer-renamed');
        const skipped = getToolElementById('mc-namer-skipped');

        if (renamed) renamed.textContent = String(STATE.renamedCount);
        if (skipped) skipped.textContent = String(STATE.skippedCount);
    }

    function log(message, type = 'info') {
        const logBox = getToolElementById('mc-namer-log');
        if (!logBox) return;

        const line = document.createElement('div');
        line.className = `mc-log-${type}`;
        line.textContent = message;
        appendBoundedToolLog(logBox, line);
    }

    function debug(message) {
        if (!STATE.debug) return;
        log(`[DEBUG] ${message}`, 'debug');
    }

    const handlePersonnelRegistryStorage = event => {
        if (event?.key !== PERSONNEL_TRAINING_REGISTRY_STORAGE_KEY) return;
        if (PERSONNEL_TRAINING_REGISTRY_DIRTY) return;
        PERSONNEL_TRAINING_REGISTRY_CACHE = null;
    };

    const handleToolPageHide = event => {
        flushPersonnelTrainingRegistry(true);
        if (event?.persisted) return;
        runToolLifecycleCleanup();
    };

    window.addEventListener('storage', handlePersonnelRegistryStorage);
    window.addEventListener('pagehide', handleToolPageHide);
    registerToolLifecycleCleanup(() => {
        window.removeEventListener('storage', handlePersonnelRegistryStorage);
        window.removeEventListener('pagehide', handleToolPageHide);
    });

    initWhenReady();

})();
    } catch (error) {
        console.error('[MissionChief Complete Tools] Naming/Personnel module startup failed:', error);
    }

    try {
        /* ==================================================================
         * MODULE 2: MISSION FINDER V10.6.86
         * Original source retained below, excluding only its metadata block.
         * ================================================================== */
(function() {
    'use strict';

    const MF_IS_TOP_WINDOW = (() => {
        try {
            return window.top === window.self;
        } catch (error) {
            return true;
        }
    })();

    function isMissionPage() {
        return !!document.querySelector('#mission_general_info');
    }

    if (window.missionFinder2026Initialized) return;

    window.missionFinder2026Initialized = true;
    window.missionFinderInitialized = true;

    let autoModeRunning =
        sessionStorage.getItem('mf_auto_mode_running') === 'true' ||
        localStorage.getItem('mf_auto_mode_running') === 'true';
    let autoModeLoopActive = false;

    // V10.1.1 Queue Restart:
    // Uses MissionChief's #mission_next_mission_btn BEFORE dispatch.
    // The previous attempt failed because after the final dispatch MissionChief can leave the same
    // mission screen visible, causing Auto Mode to process it again. This flag prevents that.
    const MF_FINAL_QUEUE_DISPATCH_FLAG = 'mf_final_queue_dispatch_clicked_v10';
    const MF_QUEUE_WAIT_ACTIVE_FLAG = 'mf_queue_wait_active_v10';
    const MF_QUEUE_OPENING_MISSION_FLAG = 'mf_queue_opening_mission_v10';
    let mfQueueRestartEnabled = localStorage.getItem('mf_next_queue_restart_enabled_v10') !== 'false';
    let mfQueueRestartThreshold = parseInt(localStorage.getItem('mf_next_queue_restart_threshold_v10_1_3') || '20', 10);
    let mfQueueRestartWaiting = false;
    let mfSilentQueueWatcherTimer = null;
    let mfSilentQueueOpening = false;
    let mfGlobalTransportWatcherTimer = null;
    let mfGlobalTransportClicking = false;
    let mfLastTransportFingerprint = '';
    let mfLastTransportClickAt = 0;
    let mfBruteApproachWatcherTimer = null;
    let mfBruteApproachClicking = false;
    let mfBruteLastFingerprint = '';
    let mfBruteLastClickAt = 0;
    let mfTransportApproachClicking = false;
    let mfTransportLastClickAt = 0;
    let mfTransportSequenceActive = false;
    let mfTransportContinuationRunning = false;
    let mfPostTransportRehookTimer = null;
    let mfPostTransportOpening = false;
    let mfTransportOwnerModal = null;
    let mfTransportOwnerApproachGoneAt = 0;
    let mfTransportOwnerCloseAttemptedAt = 0;
    let mfTransportMainStableAt = 0;
    let mfMissionUpdateFirstPassRequired = true;
    let mfMissionUpdateFirstPassMissionKey = '';
    let mfMissionUpdateFirstPassCompletedAt = 0;
    let mfLastQueueThresholdStatusAt = 0;
    let mfLastQueueThresholdStatusKey = '';
    const MF_MANUAL_AUTO_STOP_FLAG = 'mf_manual_auto_stop_v10_3_9u';
    const MF_MAIN_MISSION_OPEN_LOCK_KEY = 'mf_main_mission_open_lock_until_v10_3_9v';
    const MF_MAIN_MISSION_OPEN_REASON_KEY = 'mf_main_mission_open_reason_v10_3_9v';
    const MF_TRANSPORT_REHOOK_LOCK_KEY = 'mf_transport_rehook_lock_until_v10_3_9x';
    const MF_TRANSPORT_REHOOK_REASON_KEY = 'mf_transport_rehook_reason_v10_3_9x';
    const MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY = 'mf_transport_rehook_recent_until_v10_3_9y';
    const MF_MAIN_MISSION_PENDING_UNTIL_KEY = 'mf_main_mission_pending_until_v10_3_9zc';
    const MF_MAIN_MISSION_PENDING_TARGET_KEY = 'mf_main_mission_pending_target_v10_3_9zc';
    const MF_MAIN_MISSION_PENDING_REASON_KEY = 'mf_main_mission_pending_reason_v10_3_9zc';
    const MF_TRANSPORT_CLICK_LOCK_UNTIL_KEY = 'mf_transport_click_lock_until_v10_3_9zd';
    const MF_TRANSPORT_LAST_CLICK_AT_KEY = 'mf_transport_last_click_at_v10_3_9zd';
    const MF_TRANSPORT_LAST_CLICK_REASON_KEY = 'mf_transport_last_click_reason_v10_3_9zd';
    const MF_TRANSPORT_SHELL_WAIT_MS = 7000;
    const MF_TRANSPORT_MAIN_STABLE_MS = 3000;
    // V10.6.58: Auto Mode readiness is event/stability driven. These shorter
    // bounds still allow late patient/update DOM to appear without imposing a
    // fixed multi-second pause on every normal mission.
    const MF_UPDATE_FIRST_MIN_WAIT_MS = 800;
    const MF_UPDATE_FIRST_MAX_WAIT_MS = 3200;
    const MF_UPDATE_FIRST_STABLE_MS = 350;

    const MF_AUTO_UPGRADE_PENDING_KEY =
        'mf_auto_upgrade_pending_v10_6_13';

    const MF_AUTO_ADVANCE_AFTER_DISPATCH_KEY =
        'mf_advance_after_dispatch_v10_6_24_share_only';

    const MF_AUTO_ADVANCE_MAX_AGE_MS =
        60000;

    let mfAutoAdvanceResumeActive = false;

    let mfAutoSelectionMissionId = '';
    let mfAutoSelectionCompletedAt = 0;

    function clearAutoSelectionMissionGuard(
        reason = ''
    ) {
        mfAutoSelectionMissionId = '';
        mfAutoSelectionCompletedAt = 0;

        if (
            reason &&
            mfDebugEnabled
        ) {
            debugLog(
                'AUTO SELECTION GUARD',
                `Cleared | ${reason}`
            );
        }
    }

    function markAutoSelectionCompletedForCurrentMission(
        reason = ''
    ) {
        const missionId =
            getCurrentMissionIdForQueueRestart();

        mfAutoSelectionMissionId =
            missionId ||
            '';

        mfAutoSelectionCompletedAt =
            Date.now();

        if (mfDebugEnabled) {
            debugLog(
                'AUTO SELECTION GUARD',
                `Completed | mission=${missionId || 'unknown'} | reason=${reason || 'unknown'}`
            );
        }

        return !!missionId;
    }

    function isAutoSelectionValidForCurrentMission() {
        const missionId =
            getCurrentMissionIdForQueueRestart();

        return !!(
            missionId &&
            mfAutoSelectionMissionId &&
            missionId ===
                mfAutoSelectionMissionId &&
            mfAutoSelectionCompletedAt > 0
        );
    }

    const MF_AUTO_UPGRADE_PENDING_MAX_AGE_MS =
        90000;

    const MF_AUTO_UPGRADE_WAIT_MS =
        4000;

    const MF_AUTO_UPGRADE_MAX_PASSES =
        4;

    const MF_AUTO_UPGRADE_ENABLED_KEY =
        'mf_auto_upgrade_enabled_v10_6_33';

    // V10.6.54: The post-dispatch mission-upgrade watcher has been retired.
    // Auto Mode now uses the proven direct route: dispatch, then move straight
    // to the next mission. Keep the legacy variables/functions only for safe
    // compatibility with the established code paths, but never enable them.
    let mfAutoUpgradeCheckEnabled = false;
    let mfAutoUpgradeResumeActive = false;

    try {
        localStorage.removeItem(
            MF_AUTO_UPGRADE_ENABLED_KEY
        );
        sessionStorage.removeItem(
            MF_AUTO_UPGRADE_PENDING_KEY
        );
        localStorage.removeItem(
            MF_AUTO_UPGRADE_PENDING_KEY
        );
    } catch (error) {}

    // Remove stale ownership left by earlier post-dispatch and
    // separate Next Mission workflows.
    try {
        [
            'mf_auto_upgrade_pending_v10_6_0',
            'mf_advance_after_dispatch_v10_6_22'
        ].forEach(key => {
            sessionStorage.removeItem(key);
            localStorage.removeItem(key);
        });
    } catch (error) {}

    if (!Number.isFinite(mfQueueRestartThreshold) || mfQueueRestartThreshold < 1) {
        mfQueueRestartThreshold = 20;
    }

    // V10.2.3 safety reset:
    // Only clear stale queue flags when Auto Mode is NOT running.
    // Do NOT clear them during Auto Mode reloads, because the final-dispatch flag
    // is what stops the last mission being processed/sent twice after MissionChief
    // leaves the same mission screen open.
    if (!autoModeRunning) {
        sessionStorage.removeItem(MF_QUEUE_WAIT_ACTIVE_FLAG);
        sessionStorage.removeItem(MF_FINAL_QUEUE_DISPATCH_FLAG);
        sessionStorage.removeItem(MF_QUEUE_OPENING_MISSION_FLAG);
        sessionStorage.removeItem(
            MF_AUTO_UPGRADE_PENDING_KEY
        );
        localStorage.removeItem(
            MF_AUTO_UPGRADE_PENDING_KEY
        );

    }


    // V10.6.58: Auto Mode speed optimisation. Attachment fetching now overlaps
    // vehicle-list stabilisation, Unit Finder no longer repeats that same load
    // pass, readiness gates are shorter and state-driven, and mission-resume
    // polling is faster. Manual sources and all selection rules are unchanged.
    // V10.6.59: Police Helicopter-only requirements now select only type 11;
    // only explicit Helicopter-or-Drone rows prefer type 91 Drone first. Generic
    // 4x4 Vehicle(s) rows now use the same type 99 Mountain Rescue / type 93 SAR
    // 4x4 matcher for selection and final verification, removing false popups.
    // V10.6.62: Unit Finder now combines the mission-help attachment with
    // visible current-patient "We need:" requirements. General Live Mission
    // Requirements remain exclusive to the Mission Update workflow.
    // V10.6.63: Mission Update now converts Cars to tow in pairs (1-2 cars =
    // one Flatbed Recovery Vehicle, 3-4 = two) and current linked patient-card
    // We need alerts override a stale/zero live-panel patient row for that patient.
    // V10.6.67: Inspector and Public Order IRVs are now matched by exact
    // vehicle ID and current per-vehicle assignment-page training only. This
    // blocks duplicate generic names such as "IRV" from copying one vehicle's
    // training to another and prevents an untrained IRV from being selected.
    // Public Order qualification now requires only the L1/L2/Sergeant codes
    // actually requested by the current mission.
    // V10.6.69: Strict Inspector/Public Order verification now uses the exact
    // Personnel Assignment registry vehicle IDs as priority hints, then rechecks
    // those precise /zuweisung pages before selection. This prevents trained
    // IRVs being missed when they are outside the first arrival-sorted scan batch.
    // V10.6.71: Normal Police Car/Police Officer requirements now protect
    // exact-ID IRVs carrying specialist-trained staff, live-verify ordinary IRVs
    // before selection, and exclude known trained IRVs from ordinary attendance.
    // Auto Mode now waits for a complete, non-zero, ID-stable vehicle list with
    // no remaining load control or spinner before Unit Finder may select units.
    // V10.6.72: Exact assignment-page scans no longer require a permanent binding
    // before an untrained IRV may satisfy ordinary Police attendance. Police Medic
    // and Railway Police Officer requirements now use exact trained IRVs with two
    // qualified personnel, and ATV Carrier uses an authoritative type-30 matcher.
    // V10.6.83: Mission Control now uses an iOS Safari-only safe-area layout,
    // horizontal collapse state, visual-viewport placement and pointer dragging.
    // Desktop positioning, sizing and mouse dragging remain unchanged.
    // V10.6.86: Firefighters convert to Rescue Pumps at nine personnel
    // per vehicle; Car Recovery maps to the existing Flatbed Recovery
    // Vehicle; RIV-or-Major-Foam-Tender wording uses RIV first and only
    // falls back to a Major Foam Tender when no eligible RIV is available.
    // V10.6.85: Fire cross-reference now maps the exact "Road Rail Unit"
    // wording to the established RRU route.
    // V10.6.84: the exact mission wording "Fire, rescue or aerial appliance"
    // now maps to the existing Rescue Pump route.
    // V10.6.82: verified Fire profiles staff type-107 RRUs with two Railway Fire
    // personnel, type-15 ICCUs with three Level 1 Incident Commanders and type-39
    // Fire OSUs with three HazMat personnel. BASU, Welfare and HazMat share one OSU.
    // V10.6.81: Operational Support or SAR Vehicle requirements now select and
    // verify the exact type-86 Operational Support Van. Fire type-39 Operational
    // Support Units remain excluded from this SAR requirement.
    // V10.6.80: Critical Care Ambulances now require one trained person per vehicle.
    // Armed Response personnel use exact type-25 ATCs with two officers who each hold
    // both Roads Policing and Firearms. Police Officer and Seagoing Vessel upgrade
    // rows now use shared strict conversions across Unit Finder, Update and Auto.
    // V10.6.54: Auto Mode no longer waits for post-dispatch upgrades. It now
    // dispatches and advances immediately, including exact-next continuation
    // after high-value Dispatch & Share missions.
    // V10.6.53: ICCU-or-ACU requirements now select an ICCU first and use
    // Ambulance Control Unit vehicle type 31 only when no ICCU is available.
    // V10.6.52: Debug, High Debug and the Issue Recorder have been removed.
    // Clear legacy settings/data so they cannot be restored by an older saved preference.
    let mfDebugEnabled = false;
    let mfHighDebugEnabled = false;

    try {
        localStorage.removeItem('mf_debug_enabled_v9');
        localStorage.removeItem('mf_high_debug_enabled_v9');
        localStorage.removeItem('mf_debug_collapsed_v9');
        localStorage.removeItem('mf_issue_recorder_v1');
        localStorage.removeItem('mf_issue_recorder_enabled_v1');
    } catch (_error) {}

    function isMissionFinderIosSafariWebsite() {
        const userAgent = String(navigator.userAgent || '');
        const platform = String(navigator.platform || '');
        const isIosDevice = /iP(?:ad|hone|od)/i.test(userAgent)
            || (
                platform === 'MacIntel'
                && Number(navigator.maxTouchPoints || 0) > 1
            );
        const isSafariBrowser = /Safari/i.test(userAgent)
            && !/(?:CriOS|FxiOS|EdgiOS|OPiOS|DuckDuckGo)/i.test(userAgent);

        return isIosDevice
            && isSafariBrowser
            && /^https?:$/i.test(String(location.protocol || ''));
    }

    const MF_CONTROL_COLLAPSED_KEY =
        isMissionFinderIosSafariWebsite()
            ? 'mf_control_collapsed_ios_v1'
            : 'mf_control_collapsed_v9';
    const MF_VEHICLE_LOAD_COLLAPSED_KEY =
        isMissionFinderIosSafariWebsite()
            ? 'mf_vehicle_load_collapsed_ios_v1'
            : 'mf_vehicle_load_collapsed_v9';

    const savedVehicleLoadCollapsed =
        localStorage.getItem(
            MF_VEHICLE_LOAD_COLLAPSED_KEY
        );

    let mfVehicleLoadCollapsed =
        savedVehicleLoadCollapsed == null
            ? isMissionFinderIosSafariWebsite()
            : savedVehicleLoadCollapsed === 'true';
    let mfMissionControlCollapsed =
        localStorage.getItem(
            MF_CONTROL_COLLAPSED_KEY
        ) === 'true';

    const MF_KEEP_PANEL_POSITION_KEY = 'mf_keep_panel_position_v10_4_0';
    const MF_PANEL_LEFT_KEY = 'mf_panel_left_v10_4_0';
    const MF_PANEL_TOP_KEY = 'mf_panel_top_v10_4_0';
    const MF_SHARE_CREDIT_THRESHOLD = 15000;

    const MF_PERSONNEL_TRAINING_REGISTRY_KEY =
        'mcPersonnelVehicleTrainingRegistry_v1';

    // V10.6.67: The Personnel Tool registry can be contaminated when several
    // vehicles share the same displayed name (for example many vehicles named
    // simply "IRV"). Inspector and Public Order selection therefore trusts only
    // an exact vehicle ID that has been verified from that vehicle's current
    // /zuweisung page. Unsafe name-based registry matching is never used.
    const MF_LIVE_TRAINING_VERIFY_CACHE_MS = 10 * 60 * 1000;
    const MF_LIVE_TRAINING_VERIFY_MAX_PAGES = 48;
    const MF_LIVE_TRAINING_VERIFY_BATCH_SIZE = 6;
    const MF_STRICT_TRAINING_SOURCE_PREFIX =
        'mission-finder-live-strict-';

    // V10.6.71: ordinary Police attendance must preserve specialist IRVs.
    // Exact vehicle IDs carrying any protected Police qualification are never
    // used to satisfy a normal Police Car / Police Officer requirement.
    const MF_PROTECTED_ORDINARY_IRV_TRAINING_CODES =
        Object.freeze([
            'level_1_public_order',
            'level_2_public_order',
            'police_sergeant',
            'police_medic',
            'police_inspector',
            'traffic_police',
            'swat',
            'police_horse',
            'k9',
            'drone',
            'search_and_rescue',
            'polizeihubschrauber',
            'railway_police_command',
            'railway_police',
            'bomb_disposal_command',
            'bomb_disposal',
            'bomb_disposal_diver'
        ]);

    const MF_ORDINARY_IRV_VERIFY_MAX_PAGES = 64;
    const MF_ORDINARY_IRV_VERIFY_BATCH_SIZE = 6;
    const MF_AUTO_VEHICLE_LIST_STABLE_TIMEOUT_MS = 9000;
    const MF_AUTO_VEHICLE_LIST_STABLE_FOR_MS = 1200;
    const MF_AUTO_VEHICLE_LIST_MIN_SETTLE_MS = 1000;
    const MF_AUTO_VEHICLE_LIST_LOAD_TIMEOUT_MS = 20000;

    const mfLiveTrainingVerifyCache = new Map();

    try {
        window.addEventListener(
            'mc-personnel-training-registry-updated',
            () => {
                mfLiveTrainingVerifyCache.clear();
            }
        );
    } catch (_error) {}

    const MF_TRAINED_PERSONNEL_ROW_NAME =
        'Assigned Trained Police Vehicles';

    const MF_TRAINED_PERSONNEL_PATTERNS =
        Object.freeze([
            {
                code:
                    'level_1_public_order',
                label:
                    'Level 1 Public Order Officer',
                patterns: [
                    /(\d+)\s*(?:x\s*)?Level\s*1\s+Public\s+Order\s+Officer(?:s)?/gi,
                    /(\d+)\s*(?:x\s*)?Public\s+Order\s+Level\s*1\s+Officer(?:s)?/gi,
                    /Level\s*1\s+Public\s+Order\s+Officer(?:s)?\s*(?:x\s*)?(\d+)/gi,
                    /Public\s+Order\s+Level\s*1\s+Officer(?:s)?\s*(?:x\s*)?(\d+)/gi
                ]
            },
            {
                code:
                    'level_2_public_order',
                label:
                    'Level 2 Public Order Officer',
                patterns: [
                    /(\d+)\s*(?:x\s*)?Level\s*2\s+Public\s+Order\s+Officer(?:s)?/gi,
                    /(\d+)\s*(?:x\s*)?Public\s+Order\s+Level\s*2\s+Officer(?:s)?/gi,
                    /Level\s*2\s+Public\s+Order\s+Officer(?:s)?\s*(?:x\s*)?(\d+)/gi,
                    /Public\s+Order\s+Level\s*2\s+Officer(?:s)?\s*(?:x\s*)?(\d+)/gi
                ]
            },
            {
                code:
                    'police_sergeant',
                label:
                    'Police Sergeant',
                patterns: [
                    /(\d+)\s*(?:x\s*)?Police\s+Sergeant(?:s)?/gi,
                    /Police\s+Sergeant(?:s)?\s*(?:x\s*)?(\d+)/gi
                ]
            },
            {
                code:
                    'police_inspector',
                label:
                    'Police Inspector',
                patterns: [
                    /(\d+)\s*(?:x\s*)?Police\s+Inspector(?:s)?/gi,
                    /Police\s+Inspector(?:s)?\s*(?:x\s*)?(\d+)/gi
                ]
            },
            {
                code:
                    'police_medic',
                label:
                    'Police Medic',
                patterns: [
                    /(\d+)\s*(?:x\s*)?Police\s+Medic(?:s)?/gi,
                    /Police\s+Medic(?:s)?\s*(?:x\s*)?(\d+)/gi
                ]
            },
            {
                code:
                    'railway_police',
                label:
                    'Railway Police Officer',
                patterns: [
                    /(\d+)\s*(?:x\s*)?Railway\s+Police\s+Officer(?:s)?/gi,
                    /Railway\s+Police\s+Officer(?:s)?\s*(?:x\s*)?(\d+)/gi
                ]
            },
            {
                code:
                    'armed_response_personnel',
                label:
                    'Armed Response Personnel',
                patterns: [
                    /(\d+)\s*(?:x\s*)?(?:Required\s+)?Armed(?:\s+Response)?\s+Personnel(?:\s*\(\s*In\s+Armed\s+Vehicles\s*\))?/gi,
                    /(?:Required\s+)?Armed(?:\s+Response)?\s+Personnel(?:\s*\(\s*In\s+Armed\s+Vehicles\s*\))?\s*(?:x\s*)?(\d+)/gi
                ]
            }
        ]);

    let mfKeepPanelPosition =
        localStorage.getItem(MF_KEEP_PANEL_POSITION_KEY) === 'true';

    let mfStaffingBlockActive = false;
    let mfStaffingBlockText = '';
    let mfStaffingBlockMissionKey = '';
    const mfDebugRows = [];

    // V10.6.42 long-session performance controls.
    // V10.6.44 full-project optimisation sweep. V10.6.43 patient update controls remain intact:
    // scalable Ambulance/Critical Care counts, and global one-unit caps for
    // Ambulance Officer and Mass Casualty Equipment.
    // These handles make observers, timers and global listeners single-owner and cleanable.
    let mfMainMutationObserver = null;
    let mfMainMutationFlushTimer = null;
    let mfAutoLoopResumeTimer = null;
    let mfIssueRecorderObserver = null;
    let mfIssueRecorderMutationTimer = null;
    let mfMissionFinderResizeHandler = null;
    let mfDebugRenderFrame = null;
    let mfVehicleLoadRenderFrame = null;
    let mfRuntimeCleanupInstalled = false;
    let mfBackgroundWatcherSupervisorTimer = null;
    let mfBackgroundStorageHandler = null;
    const mfMissingUnitRetryIntervals = new Set();

    let mfVehicleCheckboxCache = {
        expiresAt: 0,
        nodes: []
    };

    let mfCheckboxVehicleValueCache = new WeakMap();
    let mfExtendedVehicleValueCache = new WeakMap();
    let mfSartecDisplayedValueCache = new WeakMap();
    let mfVehicleTypeIdentifierCache = new WeakMap();
    let mfVehicleArrivalMetricCache = new WeakMap();

    const mfVehicleMatchCandidateCache = new Map();
    const MF_VEHICLE_MATCH_CACHE_LIMIT = 240;

    const MF_RRV_REQUIREMENT_NAMES = new Set([
        'rrv',
        'rrvs',
        'required rrv',
        'required rrvs',
        'specialist paramedic rrv',
        'specialist paramedic rrvs',
        'required specialist paramedic rrv',
        'required specialist paramedic rrvs',
        'rrv or specialist paramedic rrv',
        'rrvs or specialist paramedic rrvs',
        'required rrv or specialist paramedic rrv',
        'required rrvs or specialist paramedic rrvs'
    ]);

    const MF_RRV_EXACT_VEHICLE_TYPES = new Set([
        'rrv',
        'rrvs',
        'specialist paramedic rrv',
        'specialist paramedic rrvs',
        'rapid response vehicle',
        'rapid response vehicles'
    ]);

    const MF_RIV_EXACT_VEHICLE_TYPES = new Set([
        'riv',
        'rivs',
        'rapid intervention vehicle',
        'rapid intervention vehicles',
        'rapid intervention vehicle riv',
        'rapid intervention vehicles rivs'
    ]);

    // V10.6.59: Police Air requirements have three distinct modes.
    // Only an explicit "Police Helicopter or Drone" requirement may use a
    // Drone first with a Police Helicopter as fallback. A helicopter-only row
    // must never be satisfied by a Drone, and a drone-only row must use a Drone.
    const MF_POLICE_AIR_FLEXIBLE_REQUIREMENT_NAMES = new Set([
        'police helicopter or drone',
        'police helicopter or drones',
        'police helicopters or drone',
        'police helicopters or drones',
        'required police helicopter or drone',
        'required police helicopter or drones',
        'required police helicopters or drone',
        'required police helicopters or drones'
    ]);

    const MF_POLICE_HELICOPTER_REQUIREMENT_NAMES = new Set([
        'police helicopter',
        'police helicopters',
        'required police helicopter',
        'required police helicopters',
        'policehelicopter',
        'policehelicopters'
    ]);

    const MF_POLICE_DRONE_REQUIREMENT_NAMES = new Set([
        'police drone',
        'police drones',
        'required police drone',
        'required police drones',
        'drone vehicle(police station)',
        'drone vehicle (police station)',
        'drone vehicle police station'
    ]);

    let mfMissionDocumentCache = {
        expiresAt: 0,
        documents: []
    };

    let mfMissionContextCache = {
        expiresAt: 0,
        missionKey: '',
        contexts: []
    };

    let mfTransportDocumentCache = {
        expiresAt: 0,
        documents: []
    };

    let mfTransportScopeCache = {
        expiresAt: 0,
        scopes: []
    };

    let mfPatientCountCache = {
        expiresAt: 0,
        missionKey: '',
        value: 0
    };

    let mfDispatchReadinessExpensiveCache = {
        expiresAt: 0,
        updateRowsSignature: '',
        staffingText: ''
    };

    let mfMissionUpdateRowsCache = {
        expiresAt: 0,
        missionKey: '',
        rows: []
    };

    // V10.6.57 current-mission isolation. Every shared requirement reader is
    // bound to one mission instance so a still-connected previous mission
    // iframe/modal cannot contribute requirements to the current mission.
    let mfCurrentMissionInstanceKey = '';

    const MF_INSTANCE_TOKEN =
        `mf-${Date.now()}-${Math.random().toString(36).slice(2)}`;

    const MF_SHARED_ACTIVE_INSTANCE_KEY =
        '__missionFinderActiveMissionInstanceV10_6_57';

    // V10.6.50 patient-selection ledger.
    // Patient "We need" alerts describe the total current patient demand, not
    // an additional amount to add on top of Unit Finder. MissionChief can also
    // rebuild selected vehicle rows, so the live checkbox count alone is not a
    // reliable cross-pass total. This small mission-scoped ledger prevents a
    // second Mission Update pass from doubling Ambulances/Critical Care.
    const MF_PATIENT_SELECTION_LEDGER_KEY =
        'mf_patient_selection_ledger_v10_6_50';

    let mfPatientSelectionLedgerCache = null;

    let mfMainMutationFlags = {
        relevant: false,
        vehicleListChanged: false,
        missionContextChanged: false,
        patientChanged: false,
        panelChanged: false,
        transportChanged: false
    };

    // V10.3.9R Issue Recorder:
    // Records bug context, red alerts, transport screens and trusted manual clicks so the next
    // patch can be based on what actually happened and how the user fixed it manually.
    const MF_RECORDER_KEY = 'mf_issue_recorder_v1';
    const MF_RECORDER_ENABLED_KEY = 'mf_issue_recorder_enabled_v1';
    const MF_RECORDER_MAX_ENTRIES = 40;
    const MF_RECORDER_MAX_BYTES = 1500000;
    let mfIssueRecorderEnabled = false;
    localStorage.setItem(MF_RECORDER_ENABLED_KEY, 'false');
    let mfIssueRecorderLastDangerFingerprint = '';
    let mfIssueRecorderLastDangerAt = 0;
    let mfIssueRecorderLastClickAt = 0;

    const SESSION_STATS_KEY = 'mf_session_stats_v1';
    const SESSION_REFRESH_FLAG = 'mf_session_manual_refresh_checked';
    const DEFAULT_MISSION_READY_DELAY = 1000;
    const MF_READY_DELAY_10_6_58_MIGRATION_KEY =
        'mf_ready_delay_10_6_58_migrated';

    if (
        localStorage.getItem(
            MF_READY_DELAY_10_6_58_MIGRATION_KEY
        ) !== 'true'
    ) {
        const previousSavedDelay = parseInt(
            localStorage.getItem(
                'mf_mission_ready_delay_ms'
            ) || '2000',
            10
        );

        // Migrate only the former built-in defaults. Any deliberate custom
        // delay remains untouched.
        if (
            !Number.isFinite(previousSavedDelay) ||
            previousSavedDelay === 3000 ||
            previousSavedDelay === 2000
        ) {
            localStorage.setItem(
                'mf_mission_ready_delay_ms',
                String(DEFAULT_MISSION_READY_DELAY)
            );
        }

        localStorage.setItem(
            MF_READY_DELAY_10_6_58_MIGRATION_KEY,
            'true'
        );
    }

    let missionReadyDelayMs = parseInt(
        localStorage.getItem(
            'mf_mission_ready_delay_ms'
        ) || String(DEFAULT_MISSION_READY_DELAY),
        10
    );

    if (
        !Number.isFinite(missionReadyDelayMs) ||
        missionReadyDelayMs < 500
    ) {
        missionReadyDelayMs =
            DEFAULT_MISSION_READY_DELAY;
    }

    // Clear the session dashboard on a real browser refresh, but keep it through MissionChief's internal mission reloads.
    try {
        const navEntry = performance.getEntriesByType && performance.getEntriesByType('navigation')[0];
        const isBrowserReload = navEntry && navEntry.type === 'reload';

        if (isBrowserReload && sessionStorage.getItem(SESSION_REFRESH_FLAG) !== 'true') {
            sessionStorage.removeItem(SESSION_STATS_KEY);
            sessionStorage.setItem(SESSION_REFRESH_FLAG, 'true');
        }

        if (!isBrowserReload) {
            sessionStorage.removeItem(SESSION_REFRESH_FLAG);
        }
    } catch (error) {
        console.warn('Mission Control session refresh check failed:', error);
    }

    const originalAlert = window.alert;

    function shouldAutoOkMissionFinderAlert(message) {
        const text = String(message || '').replace(/\s+/g, ' ').trim().toLowerCase();

        if (!text) return false;
        if (!autoModeRunning && sessionStorage.getItem('mf_auto_mode_running') !== 'true') return false;

        return text.includes('it lacks:') ||
            text.includes('it lacks') ||
            text.includes('lacks:') ||
            text.includes('missing vehicle') ||
            text.includes('missing vehicles') ||
            text.includes('not enough vehicle') ||
            text.includes('not enough vehicles');
    }

    window.alert = function(message) {
        try {
            recordIssueEvent('BROWSER ALERT', {
                message: String(message || ''),
                autoModeRunning,
                autoOk: shouldAutoOkMissionFinderAlert(message)
            });
        } catch (error) {}

        if (shouldAutoOkMissionFinderAlert(message)) {
            try {
                updateStatusBox(`Auto-OK alert: ${String(message || '').replace(/\s+/g, ' ').trim()}`);
            } catch (error) {}

            if (mfDebugEnabled) {
                debugLog('AUTO OK POPUP', String(message || '').replace(/\s+/g, ' ').trim());
            }

            return true;
        }

        if (autoModeRunning) {
            updateStatusBox(`Auto Mode warning: ${message}`);
        }

        originalAlert.call(window, message);
    };

    function wait(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    function recorderNowIso() {
        try {
            return new Date().toISOString();
        } catch (error) {
            return String(Date.now());
        }
    }

    function trimRecorderText(value, maxLength) {
        const max = Number.isFinite(maxLength) ? maxLength : 500;
        const text = String(value || '').replace(/\s+/g, ' ').trim();

        return text.length > max ? `${text.slice(0, max)}…` : text;
    }

    function readRecorderEntries() {
        try {
            const raw = localStorage.getItem(MF_RECORDER_KEY);
            const parsed = raw ? JSON.parse(raw) : [];
            return Array.isArray(parsed) ? parsed : [];
        } catch (error) {
            return [];
        }
    }

    function saveRecorderEntries(entries) {
        try {
            let bounded = entries.slice(-MF_RECORDER_MAX_ENTRIES);
            let encoded = JSON.stringify(bounded);

            while (
                encoded.length > MF_RECORDER_MAX_BYTES &&
                bounded.length > 1
            ) {
                bounded = bounded.slice(1);
                encoded = JSON.stringify(bounded);
            }

            localStorage.setItem(MF_RECORDER_KEY, encoded);
        } catch (_error) {
            try {
                localStorage.setItem(
                    MF_RECORDER_KEY,
                    JSON.stringify(entries.slice(-10))
                );
            } catch (_innerError) {}
        }
    }

    function getRecorderElementPath(element) {
        if (!element || !element.tagName) return '';

        const parts = [];
        let node = element;

        while (node && node.nodeType === 1 && parts.length < 6) {
            let part = node.tagName.toLowerCase();

            if (node.id) {
                part += `#${node.id}`;
                parts.unshift(part);
                break;
            }

            const className = String(node.className || '')
                .replace(/\s+/g, ' ')
                .trim()
                .split(' ')
                .filter(Boolean)
                .slice(0, 3)
                .join('.');

            if (className) part += `.${className}`;

            const parent = node.parentElement;

            if (parent) {
                const siblings = Array.from(parent.children).filter(child => child.tagName === node.tagName);
                if (siblings.length > 1) {
                    part += `:nth-of-type(${siblings.indexOf(node) + 1})`;
                }
            }

            parts.unshift(part);
            node = parent;
        }

        return parts.join(' > ');
    }

    function getRecorderVisibleButtons() {
        return Array.from(document.querySelectorAll('a, button, input[type="button"], input[type="submit"]'))
            .filter(element => {
                try {
                    const rect = element.getBoundingClientRect();
                    const style = window.getComputedStyle(element);
                    return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
                } catch (error) {
                    return false;
                }
            })
            .slice(0, 80)
            .map(element => ({
                tag: element.tagName || '',
                id: element.id || '',
                className: String(element.className || ''),
                text: trimRecorderText(element.textContent || element.value || element.title || '', 120),
                href: element.getAttribute && element.getAttribute('href') ? element.getAttribute('href') : '',
                path: getRecorderElementPath(element)
            }));
    }

    function getRecorderMissionSnapshot() {
        let queueState = null;
        let unattendedState = null;

        try {
            if (typeof getNextMissionQueueState === 'function') queueState = getNextMissionQueueState();
        } catch (error) {}

        try {
            if (typeof getUnattendedMissionStateForQueueRestart === 'function') unattendedState = getUnattendedMissionStateForQueueRestart();
        } catch (error) {}

        const alerts = Array.from(document.querySelectorAll('.alert-danger, .alert-warning, .alert-success, div[id^="alert_"]'))
            .filter(element => {
                try {
                    const style = window.getComputedStyle(element);
                    const rect = element.getBoundingClientRect();
                    return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
                } catch (error) {
                    return true;
                }
            })
            .slice(0, 8)
            .map(element => ({
                id: element.id || '',
                className: String(element.className || ''),
                text: trimRecorderText(element.innerText || element.textContent || '', 650)
            }));

        const modals = Array.from(document.querySelectorAll('.vm--modal, .modal, .lightbox'))
            .filter(element => {
                try {
                    const rect = element.getBoundingClientRect();
                    const style = window.getComputedStyle(element);
                    return rect.width > 0 && rect.height > 0 && style.display !== 'none' && style.visibility !== 'hidden';
                } catch (error) {
                    return false;
                }
            })
            .slice(0, 5)
            .map(element => ({
                className: String(element.className || ''),
                hasVehicleWindow: !!element.querySelector('.vehicle-window'),
                approachButtons: Array.from(element.querySelectorAll('button, a')).filter(button => {
                    const text = trimRecorderText(button.textContent || button.innerText || button.value || '', 50).toLowerCase();
                    return text === 'approach' || text.includes('approach');
                }).length,
                title: trimRecorderText(element.querySelector('h1,h2,h3,.modal-title')?.innerText || '', 160),
                text: trimRecorderText(element.innerText || element.textContent || '', 900)
            }));

        return {
            url: window.location.href,
            missionName: (() => { try { return getCurrentMissionName(); } catch (error) { return ''; } })(),
            missionId: (() => { try { return getCurrentMissionIdForQueueRestart(); } catch (error) { return ''; } })(),
            isMissionPage: (() => { try { return isMissionPage(); } catch (error) { return false; } })(),
            autoModeRunning,
            autoModeLoopActive,
            queueFlags: {
                finalQueueDispatch: sessionStorage.getItem(MF_FINAL_QUEUE_DISPATCH_FLAG),
                queueWaitActive: sessionStorage.getItem(MF_QUEUE_WAIT_ACTIVE_FLAG),
                queueOpeningMission: sessionStorage.getItem(MF_QUEUE_OPENING_MISSION_FLAG),
                postTransportRehookPending: sessionStorage.getItem('mf_post_transport_rehook_pending_v1') || localStorage.getItem('mf_post_transport_rehook_pending_v1'),
                transportSequenceActive: sessionStorage.getItem('mf_transport_sequence_active_v1')
            },
            queueState,
            unattendedState,
            vehicleLoadState: {
                ready: vehicleLoadState.ready,
                patients: vehicleLoadState.patients,
                ambulances: vehicleLoadState.ambulances,
                rows: (vehicleLoadState.rows || []).map(row => ({
                    originalName: row.originalName,
                    mappedName: row.mappedName,
                    required: row.required,
                    selected: row.selected,
                    status: row.status
                })).slice(0, 30)
            },
            alerts,
            modals,
            visibleButtons: getRecorderVisibleButtons(),
            debugTail: (mfDebugRows || []).slice(0, 60)
        };
    }

    // V10.6.52: Issue Recorder removed. These no-op stubs preserve compatibility
    // with existing safety/error paths without installing observers or listeners.
    function recordIssueEvent() {}
    function renderRecorderStatus() {}
    function setIssueRecorderEnabled() {}
    function clearIssueRecorder() {}
    async function copyIssueRecorder() {}
    function captureIssueNow() {}
    function scanIssueRecorderDangerAlerts() {}
    function syncIssueRecorderMutationObserver() {}
    function installIssueRecorderWatchers() {
        window.mfIssueRecorderInstalled = true;
    }

    function cleanupDuplicatePanels() {
        const wrappers = document.querySelectorAll('#mission-finder-wrapper');

        wrappers.forEach((wrapper, index) => {
            if (index > 0) {
                wrapper.remove();
            }
        });

        document.querySelectorAll('#control-panel').forEach(panel => {
            if (!panel.closest('#mission-finder-wrapper')) {
                panel.remove();
            }
        });
    }

    const crossReference = {
        /*************************************************
         * FIRE
         *************************************************/
        "Pumps": "Fire Engine R/PUMP x 1",
        "Pump": "Fire Engine R/PUMP x 1",
        "Fire engine": "Fire Engine R/PUMP x 1",
        "Fire engines": "Fire Engine R/PUMP x 1",
        "Fire Engine": "Fire Engine R/PUMP x 1",
        "Fire Engines": "Fire Engine R/PUMP x 1",
        "Aerial Appliance": "CARP",
        "Aerial Appliances": "CARP",
        "Aerial Appliance Truck": "CARP",
        "Aerial Appliance Trucks": "CARP",
        "Fire, rescue or aerial appliance": "Rescue Pump",
        "Road Rail Unit": "RRU",
        "Firefighter": "Rescue Pump",
        "Firefighters": "Rescue Pump",
        "Required Firefighter": "Rescue Pump",
        "Required Firefighters": "Rescue Pump",
        "Car Recovery": "Flatbed Recovery Vehicle",
        "Required Car Recovery": "Flatbed Recovery Vehicle",
        "ICCU or Ambulance Control Unit": "ICCU/ACU",
        "ICCU or Ambulance Control Units": "ICCU/ACU",
        "ICCUs or Ambulance Control Units": "ICCU/ACU",
        "Fire Officer": "Fire Officer",
        "Fire Officers": "Fire Officer",
        "Rescue Support Unit": "Fire Engine R/PUMP x 1",
        "Rescue Support Units": "Fire Engine R/PUMP x 1",
        "Rescue Support Vehicle": "Fire Engine R/PUMP x 1",
        "Rescue Support Vehicles": "Fire Engine R/PUMP x 1",
        "Rescue Support Unit or Rescue Pump": "Fire Engine R/PUMP x 1",
        "Rescue Support Units or Rescue Pumps": "Fire Engine R/PUMP x 1",
        "Fire Engines or Rescue Support Vehicles": "Fire Engine R/PUMP x 1",
        "Fire Engines, Rescue Support Vehicles or Aerial Appliance Trucks": "Fire Engine R/PUMP x 1",
        "Foam Unit": "RP CAFS",
        "Foam Units": "RP CAFS",
        "Water Carrier": "Water Carrier",
        "Water Carriers": "Water Carrier",
        "Welfare Vehicles x1": "Welfare Vehicle",

        /*************************************************
         * POLICE
         *************************************************/
        "Police Car": "Police Car",
        "Police Cars": "Police Car",
        "Police car": "Police Car",
        "Police cars": "Police Car",
        "Police Officer": "Police Car",
        "Police Officers": "Police Car",
        "Traffic Car": "Police ATC",
        "Traffic Cars": "Police ATC",
        "Police Cars or Armed Response Vehicles (ARVs)": "Police ATC",
        "Armed Response Personnel (In Armed Vehicles)": "Police ATC",
        "Dog Support Unit (DSU)": "Police DSU",
        "Dog Support Units (DSU)": "Police DSU",
        "Dog Support Units (DSUs)": "Police DSU",
        "Mounted Unit": "Mounted Unit",
        "Mounted Units": "Mounted Unit",
        "Police Inspector": "Police Inspector",
        "Police Sergeant": "Police Sergeant",
        "Cell Van": "Cell Van",
        "Police Helicopter": "Police Helicopter",
        "Police Helicopters": "Police Helicopter",
        "Police Helicopter or Drone": "Police Helicopter",
        "Police Helicopter or Drones": "Police Helicopter",
        "Police Helicopters or Drone": "Police Helicopter",
        "Police Helicopters or Drones": "Police Helicopter",
        "Required Police Helicopter or Drone": "Police Helicopter",
        "Required Police Helicopter or Drones": "Police Helicopter",
        "Required Police Helicopters or Drone": "Police Helicopter",
        "Required Police Helicopters or Drones": "Police Helicopter",
        "Police Drone": "Police Helicopter",
        "Police Drones": "Police Helicopter",
        "Policehelicopter": "Police Helicopter",
        "Policehelicopters": "Police Helicopter",
        "modules.missionHelper.vehicles.captions.railway_police": "railway police",
        "modules.missionHelper.prerequisites.railway_police": "EIU",
        "modules.missionHelper.prerequisites.railway_police_command": "EIU",

        /*************************************************
         * AMBULANCE
         *************************************************/
        "Ambulance": "Ambulance",
        "Ambulances": "Ambulance",
        "Ambulance Officer": "Ambulance Officer",
        "Ambulance Officers": "Ambulance Officer",
        "Required Ambulance Officer": "Ambulance Officer",
        "Required Ambulance Officers": "Ambulance Officer",
        "Primary Response Vehicle": "PRV",
        "Primary Response Vehicles": "PRV",
        "PRVs": "PRV",
        "Secondary Response Vehicle": "SRV",
        "Secondary Response Vehicles": "SRV",
        "SRVs": "SRV",
        "Operational Team Leader": "OTL",
        "Operational Team Leaders": "OTL",
        "Mass Casualty Equipment": "Mass Casualty Equipment",
        "Mass Casualty Equipment Unit": "Mass Casualty Equipment",
        "Mass Casualty Equipment Units": "Mass Casualty Equipment",
        "Critical Care": "Critical Care",
        "Critical Care Team": "Critical Care",
        "Critical Care Teams": "Critical Care",
        "Required Critical Care": "Critical Care",
        "Required Critical Care Team": "Critical Care",
        "Required Critical Care Teams": "Critical Care",
        "ATV Carrier": "ATV Carrier",
        "ATV Carriers": "ATV Carrier",
        "ATC Carrier": "ATV Carrier",
        "ATC Carriers": "ATV Carrier",
        "RRV": "RRV",
        "RRVs": "RRV",
        "Required RRV": "RRV",
        "Required RRVs": "RRV",
        "Specialist Paramedic RRV": "RRV",
        "Specialist Paramedic RRVs": "RRV",
        "Required Specialist Paramedic RRV": "RRV",
        "Required Specialist Paramedic RRVs": "RRV",
        "RRV or Specialist Paramedic RRV": "RRV",
        "RRVs or Specialist Paramedic RRVs": "RRV",
        "Required RRV or Specialist Paramedic RRV": "RRV",
        "Required RRVs or Specialist Paramedic RRVs": "RRV",
        "Community Midwife": "Community Midwife",
        "Community Midwifes": "Community Midwife",

        /*************************************************
         * COASTGUARD / LIFEBOAT
         *************************************************/
        "CRV": "CRV",
        "CRVs": "CRV",
        "Inland Rescue Boat (Trailer)": "Inland Rescue Boat (Trailer)",
        "Boat Trailer or Inland Rescue Boat": "Boat Trailer",
        "Seagoing Vessel": "ALB",
        "Seagoing Vessels": "ALB",
        "Coastguard Rescue Helicopter": "CG Rescue Helicopter (Large)",
        "Coastguard Rescue Helicopters": "CG Rescue Helicopter (Large)",
        "Coastguard Rescue Helicopter (20%)": "CG Rescue Helicopter (Large)",
        "ILBs or ALBs": "ALB",
        "ALBs": "ALB",
        "ALB": "ALB",
        "ILBs": "ILB",
        "ILB": "ILB",
        "Control Van": "Control Van",
        "Control Vans": "Control Van",
        "SAR Commander": "Control Van",
        "SAR Commanders": "Control Van",
        "Required SAR Commander": "Control Van",
        "Required SAR Commanders": "Control Van",
        "Search Advisor": "SARTEC",
        "Search Advisors": "SARTEC",
        "Operational Support Van": "Operational Support Van",
        "Operational Support Vans": "Operational Support Van",
        "Operational Support or SAR Vehicle": "Operational Support Van",
        "Operational Support or SAR Vehicles": "Operational Support Van",
        "Operational Support or SAR Vehicle x1": "Operational Support Van",
        "Operational Support Van or SAR Vehicle": "Operational Support Van",
        "Operational Support Vans or SAR Vehicles": "Operational Support Van",
        "Operational Support Vehicle or SAR Vehicle": "Operational Support Van",
        "Operational Support Vehicles or SAR Vehicles": "Operational Support Van",
        "Operational Support or Personal SAR Vehicle": "Operational Support Van",
        "Operational Support or Personal SAR Vehicles": "Operational Support Van",
        "Required Operational Support or SAR Vehicle": "Operational Support Van",
        "Required Operational Support or SAR Vehicles": "Operational Support Van",
        "Operational Support Van, Trailer or Personal SAR Vehicle": "Operational Support Van",
        "Operational Support Vans, Trailers or Personal SAR Vehicles": "Operational Support Van",
        "Operational Support Van Trailer or Personal SAR Vehicle": "Operational Support Van",
        "Operational Support Vans Trailers or Personal SAR Vehicles": "Operational Support Van",
        "Operational Support Van or Personal SAR Vehicle": "Operational Support Van",
        "Operational Support Vans or Personal SAR Vehicles": "Operational Support Van",
        "OSV": "Operational Support Van",
        "OSVs": "Operational Support Van",
        "Hovercraft (trailer)": "Hovercraft (trailer)",
        "Coastguard Mud Rescue Unit": "Coastguard Mud Rescue Unit",
        "Coastguard Mud Rescue Units": "Coastguard Mud Rescue Unit",
        "Mud Decontamination Unit": "Mud Decontamination Unit",
        "Mud Decontamination Units": "Mud Decontamination Unit",
        "Coastguard Commander": "CG Commander",
        "Flood Rescue Units":"Flood Rescue",

        /*************************************************
         * AIRFIELD OPS
         *************************************************/
        "Airfield Operations Vehicle": "Airfield Operations Vehicle",
        "Airfield Operations Vehicles": "Airfield Operations Vehicle",
        "Aerial Appliance Trucks or Rescue Stairs": "Rescue Stairs",
        "Fire Engines or RIVs": "RIV",
        "RIV": "RIV",
        "RIVs": "RIV",
        "Rapid Intervention Vehicle": "RIV",
        "Rapid Intervention Vehicles": "RIV",
        "Major Foam Tender": "Major Foam Tender",
        "Major Foam Tenders": "Major Foam Tender",
        "RIVs or Major Foam Tenders": "RIV",
        "RIV or Major Foam Tender": "RIV",
        "Required RIV or Major Foam Tender": "RIV",
        "Required RIVs or Major Foam Tenders": "RIV",
        "Fire Engines, RIVs or Major Foam Tenders": "Major Foam Tender",
        "Fire Engines or Major Foam Tenders": "Major Foam Tender",
        "Airfield Operations Supervisor": "Airfield Operations Supervisors",
        "Airfield Operations Supervisors": "Airfield Operations Supervisors",
        "Airfield Firefighting Command Vehicle": "Airfield FF Command Vehicle",
        "ICCU or Ambulance Control Units or Airfield Firefighting Command Vehicles": "Airfield FF Command Vehicle",
        "Fire Officers or Airfield Firefighting Command Vehicles": "Fire Officer",

        /*************************************************
         * SEARCH & RESCUE / FLOOD / RECOVERY / BOMB
         *************************************************/
        "Flood Rescue Unit": "Flood Rescue Unit (Trailer)",
        "4x4 Vehicle": "4x4 Units",
        "4x4 Vehicles": "4x4 Units",
        "Mountain Rescue 4x4 or SAR 4x4": "4x4 Units",
        "Mountain Rescue 4x4s or SAR 4x4s": "4x4 Units",

        // Special Search Technician vehicle selector.
        // Matching is handled by the dedicated displayed-name-prefix rule.
        "SARTEC": "SARTEC",

        "modules.missionHelper.prerequisites.tow_trucks_large": "Flatbed Recovery Vehicle",
        "modules.missionHelper.prerequisites.tow_trucks": "Flatbed Recovery Vehicle",
        "1 car to tow": "Flatbed Recovery Vehicle",
        "Cars to tow": "Flatbed Recovery Vehicle",
        "Car to tow": "Flatbed Recovery Vehicle",
        "Maximum amount of cars to tow": "Flatbed Recovery Vehicle",
        "Minimum amount of cars to tow": "Flatbed Recovery Vehicle",
        "Tow Trucks Large": "Flatbed Recovery Vehicle",
        "Flatbed Recovery Vehicle": "Flatbed Recovery Vehicle",
        "Flatbed Recovery Vehicles": "Flatbed Recovery Vehicle",
        "modules.missionHelper.vehicles.captions.bomb_disposal_crew": "Bomb Disposal crew x1",
        "Support Units": "Support Unit",
        "Breathing Apparatus Support Unit": "OSU",
        "Breathing Apparatus Support Units": "OSU",
        "Breathing Apparatus Support Vehicle": "OSU",
        "Breathing Apparatus Support Vehicles": "OSU",
        "BASU": "OSU",
        "BASUs": "OSU",
        "Welfare": "OSU",
        "Welfare Unit": "OSU",
        "Welfare Units": "OSU",
        "Welfare Vehicle": "OSU",
        "Welfare Vehicles": "OSU",
        "HazMat": "OSU",
        "Hazmat": "OSU",
        "HazMat Unit": "OSU",
        "HazMat Units": "OSU",
        "Hazmat Unit": "OSU",
        "Hazmat Units": "OSU",
        "HazMat Unit or CBRN Vehicle": "OSU",
        "HazMat Units or CBRN Vehicles": "OSU",
        "Hazmat Unit or CBRN Vehicle": "OSU",
        "Hazmat Units or CBRN Vehicles": "OSU",
        "CBRN Vehicle": "OSU",
        "CBRN Vehicles": "OSU",
        "Operational Support Unit": "OSU",
        "Operational Support Units": "OSU",
        "Fire Operational Support Unit": "OSU",
        "Fire Operational Support Units": "OSU",
        "Breathing Apparatus Support Unit x1": "OSU",
        "Breathing Apparatus Support Units x1": "OSU",
        "BASU x1": "OSU",
        "BASUs x1": "OSU",
        "Welfare Vehicle x1": "OSU",
        "Welfare Vehicles x1": "OSU",
        "HazMat Unit or CBRN Vehicle x1": "OSU",
        "HazMat Units or CBRN Vehicles x1": "OSU",
        "Operational Support Unit x1": "OSU",
        "Operational Support Units x1": "OSU",
    };

    const crossReferenceNormalisedLookup = new Map(
        Object.entries(crossReference).map(([key, value]) => [
            String(key || '').replace(/\s+/g, ' ').trim().toLowerCase(),
            value
        ])
    );

    let vehicleLoadState = {
        rows: [],
        patients: 0,
        ambulances: 0,
        ambulanceOfficer: false,
        ready: false
    };


    // V9.2.1: selection protection. This stops the same source asking for the same vehicle twice
    // during one Unit Finder / Auto Mode cycle. Counters are visual only and never drive dispatch.
    let processedSelectionKeys = new Set();

    function buildSelectionKey(source, originalName, mappedName, amount) {
        // Include the original requirement as well as the mapped unit.
        // Different requirements can legitimately map to similar/related vehicles,
        // so mapped-name-only guards can wrongly block valid dispatches.
        return `${String(source || 'UNKNOWN').toUpperCase()}|${normaliseVehicleText(originalName)}|${normaliseVehicleText(mappedName)}|${Math.max(0, parseInt(amount, 10) || 0)}`;
    }

    function clearSelectionGuards() {
        processedSelectionKeys = new Set();
    }

    function withTimeout(promise, timeoutMs, label) {
        return new Promise((resolve, reject) => {
            const timeoutId = setTimeout(() => {
                reject(
                    new Error(
                        `${label || 'Operation'} timed out after ${timeoutMs}ms`
                    )
                );
            }, timeoutMs);

            Promise.resolve(promise).then(
                value => {
                    clearTimeout(timeoutId);
                    resolve(value);
                },
                error => {
                    clearTimeout(timeoutId);
                    reject(error);
                }
            );
        });
    }

    // V10.6.52 compatibility stubs. Existing operational code can retain its
    // guarded diagnostic calls without creating log arrays, timers, DOM nodes
    // or browser-console history.
    function debugLog() {}
    function highDebugLog() {}
    function setDebugEnabled() {}
    function setHighDebugEnabled() {}
    function clearDebugLog() {}
    async function copyDebugLog() {}
    function renderDebugPanelNow() {}
    function renderDebugPanel() {}

    function getVehicleDebugName(element) {
        if (!element) return 'not found';
        const row = element.closest && element.closest('tr');
        const values = [
            element.getAttribute && element.getAttribute('vehicle_caption'),
            element.getAttribute && element.getAttribute('vehicle_type_caption'),
            element.getAttribute && element.getAttribute('search_attribute'),
            row && row.getAttribute('vehicle_caption'),
            row && row.getAttribute('vehicle_type_caption'),
            row && row.querySelector('td:nth-child(2)') && row.querySelector('td:nth-child(2)').innerText
        ].filter(Boolean);
        return values.length ? values[0].replace(/\s+/g, ' ').trim() : element.tagName;
    }

    function resolveUnitName(unitName) {
        const cleaned = String(unitName || '')
            .replace(/\s+/g, ' ')
            .trim();

        if (!cleaned) return '';

        return (
            crossReference[cleaned] ||
            crossReferenceNormalisedLookup.get(
                cleaned.toLowerCase()
            ) ||
            cleaned
        );
    }

    function normaliseVehicleText(value) {
        return String(value || '')
            .replace(/&amp;/g, '&')
            .replace(/\s+/g, ' ')
            .trim()
            .toLowerCase();
    }

    function isSartecRequirement(
        originalName,
        mappedName
    ) {
        return (
            normaliseVehicleText(
                originalName
            ) === 'sartec' ||
            normaliseVehicleText(
                mappedName
            ) === 'sartec'
        );
    }

    function normaliseSartecDisplayedName(
        value
    ) {
        return String(value || '')
            .replace(/&amp;/g, '&')
            .replace(/\s+/g, ' ')
            .trim()
            // Ignore leading emoji, coloured circles and punctuation.
            .replace(/^[^A-Za-z0-9]+/, '')
            .trim();
    }

    function isIccuOrAmbulanceControlRequirement(
        originalName,
        mappedName
    ) {
        const raw =
            normaliseVehicleText(
                originalName
            );

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        const supported = new Set([
            'iccu or ambulance control unit',
            'iccu or ambulance control units',
            'iccus or ambulance control unit',
            'iccus or ambulance control units',
            'iccu/acu'
        ]);

        return (
            supported.has(raw) ||
            supported.has(mapped)
        );
    }

    function isIccuVehicleCheckbox(
        input
    ) {
        return getExtendedVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value === 'iccu' ||
                value === 'iccus' ||
                value === 'incident command and control unit' ||
                value === 'incident command and control units' ||
                /(?:^|\b)ICCU(?:s)?(?:\b|$)/i.test(cleaned) ||
                /(?:^|\b)Incident\s+Command\s+(?:and|&)\s+Control\s+Unit(?:s)?(?:\b|$)/i.test(cleaned)
            );
        });
    }

    function isAmbulanceControlUnitCheckbox(
        input
    ) {
        const typeIdentifiers =
            getVehicleTypeIdentifiers(
                input
            );

        // MissionChief UK Ambulance Control Unit vehicle type.
        if (
            typeIdentifiers.includes(
                '31'
            )
        ) {
            return true;
        }

        return getExtendedVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value === 'acu' ||
                value === 'acus' ||
                value === 'ambulance control unit' ||
                value === 'ambulance control units' ||
                /(?:^|\b)ACU(?:s)?(?:\b|$)/i.test(cleaned) ||
                /(?:^|\b)Ambulance\s+Control\s+Unit(?:s)?(?:\b|$)/i.test(cleaned)
            );
        });
    }

    function get4x4RequirementMode(
        originalName,
        mappedName
    ) {
        const raw =
            normaliseVehicleText(
                originalName
            );

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        const specialistRequirements = new Set([
            'mountain rescue 4x4 or sar 4x4',
            'mountain rescue 4x4s or sar 4x4s',
            'required mountain rescue 4x4 or sar 4x4',
            'required mountain rescue 4x4s or sar 4x4s'
        ]);

        // Check the explicit specialist wording first. Its mapped display name
        // is also "4x4 Units", but it must continue to use only Mountain Rescue
        // 4x4 / SAR 4x4 vehicles rather than the normal type-66 4x4 Vehicle.
        if (
            specialistRequirements.has(raw) ||
            specialistRequirements.has(mapped)
        ) {
            return 'mountain-or-sar';
        }

        const genericRequirements = new Set([
            '4x4 vehicle',
            '4x4 vehicles',
            '4x4 unit',
            '4x4 units',
            'required 4x4 vehicle',
            'required 4x4 vehicles',
            'required 4x4 unit',
            'required 4x4 units'
        ]);

        if (
            genericRequirements.has(raw) ||
            genericRequirements.has(mapped)
        ) {
            return 'generic';
        }

        return '';
    }

    function isGeneric4x4VehicleRequirement(
        originalName,
        mappedName
    ) {
        return get4x4RequirementMode(
            originalName,
            mappedName
        ) === 'generic';
    }

    function isMountainRescueOrSar4x4Requirement(
        originalName,
        mappedName
    ) {
        return get4x4RequirementMode(
            originalName,
            mappedName
        ) === 'mountain-or-sar';
    }

    function isGeneric4x4VehicleCheckbox(
        input
    ) {
        if (!input) return false;

        // MissionChief UK normal 4x4 Vehicle. Type 66 is authoritative and
        // keeps custom-named vehicles linked to the generic requirement row.
        if (
            getVehicleTypeIdentifiers(
                input
            ).includes('66')
        ) {
            return true;
        }

        return getExtendedVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value === '4x4 vehicle' ||
                value === '4x4 vehicles' ||
                /^(?:Required\s+)?4x4\s+Vehicle(?:s)?$/i
                    .test(
                        cleaned
                    )
            );
        });
    }

    function isMountainRescue4x4Checkbox(
        input
    ) {
        if (!input) return false;

        // MissionChief UK Mountain Rescue 4x4 vehicle type. Type matching is
        // authoritative and continues to work when the vehicle has a custom name.
        if (
            getVehicleTypeIdentifiers(
                input
            ).includes('99')
        ) {
            return true;
        }

        return getExtendedVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value ===
                    'mountain rescue 4x4' ||
                value ===
                    'mountain rescue 4x4s' ||
                /(?:^|\b)Mountain\s+Rescue\s+4x4(?:s)?(?:\b|$)/i
                    .test(
                        cleaned
                    )
            );
        });
    }

    function isSar4x4Checkbox(
        input
    ) {
        if (!input) return false;

        // MissionChief UK SAR 4x4 vehicle type. Type matching is authoritative
        // and continues to work when the vehicle has a custom name.
        if (
            getVehicleTypeIdentifiers(
                input
            ).includes('93')
        ) {
            return true;
        }

        return getExtendedVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value ===
                    'sar 4x4' ||
                value ===
                    'sar 4x4s' ||
                /(?:^|\b)SAR\s+4x4(?:s)?(?:\b|$)/i
                    .test(
                        cleaned
                    )
            );
        });
    }

    function getSartecDisplayedVehicleValues(
        input
    ) {
        if (!input) return [];

        const cached =
            mfSartecDisplayedValueCache.get(
                input
            );

        if (cached) return cached;

        const row =
            input.closest &&
            input.closest('tr');

        const labelById =
            input.id
                ? document.getElementById(
                    `label_${input.id}`
                )
                : null;

        const rowLabel =
            row && input.id
                ? Array.from(
                    row.querySelectorAll(
                        'label[for]'
                    )
                ).find(
                    label =>
                        label.htmlFor ===
                        input.id
                )
                : null;

        const values = [
            labelById?.textContent,
            labelById?.innerText,
            rowLabel?.textContent,
            rowLabel?.innerText,
            input.getAttribute &&
                input.getAttribute(
                    'vehicle_caption'
                ),
            input.getAttribute &&
                input.getAttribute(
                    'search_attribute'
                ),
            row &&
                row.getAttribute(
                    'vehicle_caption'
                ),
            row &&
                row.getAttribute(
                    'search_attribute'
                ),
            row &&
                row.querySelector(
                    'td:nth-child(2)'
                )?.innerText
        ]
            .filter(Boolean)
            .map(
                normaliseSartecDisplayedName
            );

        mfSartecDisplayedValueCache.set(
            input,
            values
        );

        return values;
    }

    function isSartecVehicleCheckbox(
        input
    ) {
        return getSartecDisplayedVehicleValues(
            input
        ).some(value => {
            // Whole-word prefix only. Everything after SARTEC is ignored.
            return /^SARTEC\b/i.test(
                value
            );
        });
    }

    function isRrvRequirement(
        originalName,
        mappedName
    ) {
        const raw =
            normaliseVehicleText(
                originalName
            );

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        return (
            MF_RRV_REQUIREMENT_NAMES.has(raw) ||
            MF_RRV_REQUIREMENT_NAMES.has(mapped)
        );
    }

    function getRrvVehicleValues(input) {
        return getExtendedVehicleValues(input);
    }

    function isRrvVehicleCheckbox(
        input
    ) {
        return getRrvVehicleValues(
            input
        ).some(value => {
            if (
                MF_RRV_EXACT_VEHICLE_TYPES.has(value)
            ) {
                return true;
            }

            // Match RRV as a complete displayed-name prefix/token.
            // This deliberately does not match RIV or unrelated text.
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                /^RRV\b/i.test(
                    cleaned
                ) ||
                /^Specialist\s+Paramedic\s+RRV\b/i.test(
                    cleaned
                ) ||
                /^Rapid\s+Response\s+Vehicle\b/i.test(
                    cleaned
                )
            );
        });
    }


    function isRivOrMajorFoamTenderRequirement(
        originalName,
        mappedName
    ) {
        const raw =
            String(
                originalName || ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        return (
            /^(?:Required\s+)?RIVs?\s+or\s+Major\s+Foam\s+Tenders?$/i.test(
                raw
            ) ||
            mapped ===
                'riv or major foam tender' ||
            mapped ===
                'rivs or major foam tenders'
        );
    }

    function isMajorFoamTenderVehicleCheckbox(
        input
    ) {
        if (!input) return false;

        if (
            getVehicleTypeIdentifiers(
                input
            ).includes(
                '75'
            )
        ) {
            return true;
        }

        return getCheckboxVehicleValues(
            input
        ).some(value => {
            return (
                value ===
                    'major foam tender' ||
                value ===
                    'major foam tenders' ||
                value ===
                    'mft'
            );
        });
    }

    function isRivRequirement(
        originalName,
        mappedName
    ) {
        const raw =
            normaliseVehicleText(
                originalName
            );

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        return (
            mapped === 'riv' ||
            mapped === 'rivs' ||
            mapped ===
                'rapid intervention vehicle' ||
            mapped ===
                'rapid intervention vehicles' ||
            raw === 'riv' ||
            raw === 'rivs' ||
            raw ===
                'rapid intervention vehicle' ||
            raw ===
                'rapid intervention vehicles' ||
            raw ===
                'fire engines or rivs'
        );
    }

    function getRivVehicleValues(input) {
        return getExtendedVehicleValues(input);
    }

    function isRivVehicleCheckbox(
        input
    ) {
        return getRivVehicleValues(
            input
        ).some(value => {
            if (
                MF_RIV_EXACT_VEHICLE_TYPES.has(value)
            ) {
                return true;
            }

            // Match RIV as a complete displayed-name token only.
            // This will match "🚒 RIV - AIRFIELD-1" but not a
            // different word that merely contains the letters riv.
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                /^RIV\b/i.test(
                    cleaned
                ) ||
                /^Rapid\s+Intervention\s+Vehicle\b/i.test(
                    cleaned
                )
            );
        });
    }

    function getPoliceAirRequirementMode(
        originalName,
        mappedName
    ) {
        const raw =
            normaliseVehicleText(
                originalName
            );

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        // Check the original wording first. The cross-reference deliberately
        // maps "Police Helicopter or Drone" to Police Helicopter, so using
        // only the mapped value would lose the alternative-unit rule.
        if (
            MF_POLICE_AIR_FLEXIBLE_REQUIREMENT_NAMES.has(raw)
        ) {
            return 'flexible';
        }

        if (
            MF_POLICE_HELICOPTER_REQUIREMENT_NAMES.has(raw)
        ) {
            return 'helicopter';
        }

        if (
            MF_POLICE_DRONE_REQUIREMENT_NAMES.has(raw)
        ) {
            return 'drone';
        }

        if (
            MF_POLICE_AIR_FLEXIBLE_REQUIREMENT_NAMES.has(mapped)
        ) {
            return 'flexible';
        }

        if (
            MF_POLICE_HELICOPTER_REQUIREMENT_NAMES.has(mapped)
        ) {
            return 'helicopter';
        }

        if (
            MF_POLICE_DRONE_REQUIREMENT_NAMES.has(mapped)
        ) {
            return 'drone';
        }

        return '';
    }

    function isPoliceAirRequirement(
        originalName,
        mappedName
    ) {
        return !!getPoliceAirRequirementMode(
            originalName,
            mappedName
        );
    }

    function getPoliceAirVehicleValues(input) {
        return getExtendedVehicleValues(input);
    }

    function isPoliceHelicopterCheckbox(
        input
    ) {
        if (!input) return false;

        // MissionChief UK Police Helicopter vehicle type.
        if (
            getVehicleTypeIdentifiers(
                input
            ).includes('11')
        ) {
            return true;
        }

        return getPoliceAirVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value ===
                    'police helicopter' ||
                value ===
                    'police helicopters' ||
                value ===
                    'policehelicopter' ||
                value ===
                    'policehelicopters' ||
                /^Police\s*Helicopter(?:s)?\b/i.test(
                    cleaned
                )
            );
        });
    }

    function isPoliceDroneCheckbox(
        input
    ) {
        if (!input) return false;

        // MissionChief UK Drone Vehicle (Police Station) vehicle type.
        if (
            getVehicleTypeIdentifiers(
                input
            ).includes('91')
        ) {
            return true;
        }

        return getPoliceAirVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value ===
                    'police drone' ||
                value ===
                    'police drones' ||
                value ===
                    'drone vehicle(police station)' ||
                value ===
                    'drone vehicle (police station)' ||
                value ===
                    'drone vehicle police station' ||
                /^Police\s+Drone(?:s)?\b/i.test(
                    cleaned
                ) ||
                /^Drone\s+Vehicle\s*\(\s*Police\s+Station\s*\)(?:\s|$)/i.test(
                    cleaned
                )
            );
        });
    }


    function isPoliceCarRequirement(
        originalName,
        mappedName
    ) {
        const raw =
            normaliseVehicleText(
                originalName
            );

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        return (
            raw ===
                'police car' ||
            raw ===
                'police cars' ||
            raw ===
                'police officer' ||
            raw ===
                'police officers' ||
            mapped ===
                'police car' ||
            mapped ===
                'police cars'
        );
    }

    function getVehicleTypeIdentifiers(input) {
        if (!input) return [];

        const cached = mfVehicleTypeIdentifierCache.get(input);
        if (cached) return cached;

        const row = input.closest?.('tr');
        const typeCell = row?.querySelector?.(
            '[vehicle_type_id], [data-vehicle-type-id]'
        );

        const identifiers = [
            input.getAttribute?.('vehicle_type'),
            input.getAttribute?.('vehicle_type_id'),
            input.getAttribute?.('data-vehicle-type'),
            input.getAttribute?.('data-vehicle-type-id'),
            row?.getAttribute?.('vehicle_type'),
            row?.getAttribute?.('vehicle_type_id'),
            row?.getAttribute?.('data-vehicle-type'),
            row?.getAttribute?.('data-vehicle-type-id'),
            typeCell?.getAttribute?.('vehicle_type_id'),
            typeCell?.getAttribute?.('data-vehicle-type-id')
        ]
            .filter(value => value !== null && value !== undefined && String(value).trim() !== '')
            .map(value => String(value).trim());

        mfVehicleTypeIdentifierCache.set(input, identifiers);
        return identifiers;
    }

    function isPoliceCarVehicleCheckbox(
        input
    ) {
        if (!input) {
            return false;
        }

        const typeIdentifiers =
            getVehicleTypeIdentifiers(
                input
            );

        // MissionChief UK normal Police Car / IRV vehicle type.
        if (
            typeIdentifiers
                .includes(
                    '8'
                )
        ) {
            return true;
        }

        const values =
            getCheckboxVehicleValues(
                input
            );

        return values.some(value => {
            const cleaned =
                normaliseVehicleText(
                    value
                );

            return (
                cleaned ===
                    'police car' ||
                cleaned ===
                    'police cars' ||
                cleaned ===
                    'incident response vehicle' ||
                cleaned ===
                    'incident response vehicles' ||
                cleaned ===
                    'irv'
            );
        });
    }




    function isSeagoingVesselRequirement(originalName, mappedName) {
        const raw = normaliseVehicleText(originalName);
        const mapped = normaliseVehicleText(mappedName);
        const names = new Set([
            'seagoing vessel',
            'seagoing vessels',
            'required seagoing vessel',
            'required seagoing vessels',
            'alb',
            'albs',
            'abl',
            'abls',
            'all weather lifeboat',
            'all weather lifeboats',
            'all-weather lifeboat',
            'all-weather lifeboats'
        ]);
        return names.has(raw) || names.has(mapped);
    }

    function isSeagoingVesselCheckbox(input) {
        if (!input) return false;

        const accepted = new Set([
            'alb',
            'albs',
            'abl',
            'abls',
            'all weather lifeboat',
            'all weather lifeboats',
            'all-weather lifeboat',
            'all-weather lifeboats',
            'seagoing vessel',
            'seagoing vessels'
        ]);

        return getExtendedVehicleValues(input).some(value => {
            return accepted.has(normaliseVehicleText(value));
        });
    }

    function isArmedTrafficCarVehicleCheckbox(input) {
        if (!input) return false;

        if (getVehicleTypeIdentifiers(input).includes('25')) {
            return true;
        }

        return getExtendedVehicleValues(input).some(value => {
            const cleaned = normaliseVehicleText(value);
            return (
                cleaned === 'armed traffic car' ||
                cleaned === 'armed traffic cars' ||
                cleaned === 'police atc' ||
                cleaned === 'police atcs' ||
                cleaned === 'atc' ||
                cleaned === 'atcs'
            );
        });
    }

    function isAtvCarrierRequirement(
        originalName,
        mappedName
    ) {
        const raw =
            normaliseVehicleText(
                originalName
            );

        const mapped =
            normaliseVehicleText(
                mappedName
            );

        return (
            raw === 'atv carrier' ||
            raw === 'atv carriers' ||
            raw === 'atc carrier' ||
            raw === 'atc carriers' ||
            mapped === 'atv carrier' ||
            mapped === 'atv carriers' ||
            mapped === 'atc carrier' ||
            mapped === 'atc carriers'
        );
    }

    function isAtvCarrierCheckbox(
        input
    ) {
        if (!input) return false;

        // MissionChief UK ATV Carrier / ATV vehicle type.
        if (
            getVehicleTypeIdentifiers(
                input
            ).includes('30')
        ) {
            return true;
        }

        return getExtendedVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseVehicleText(
                    value
                );

            return (
                cleaned === 'atv' ||
                cleaned === 'atv carrier' ||
                cleaned === 'atv carriers' ||
                cleaned === 'atc carrier' ||
                cleaned === 'atc carriers'
            );
        });
    }

    function isDogSupportUnitRequirement(
        originalName,
        mappedName
    ) {
        const raw = normaliseVehicleText(
            originalName
        );

        const mapped = normaliseVehicleText(
            mappedName
        );

        return (
            mapped === 'police dsu' ||
            mapped === 'dsu' ||
            raw === 'dog support unit (dsu)' ||
            raw === 'dog support units (dsu)' ||
            raw === 'dog support units (dsus)' ||
            raw === 'police dsu' ||
            raw === 'dsu' ||
            /^required\s+dog\s+support\s+units?\s*\(\s*dsus?\s*\)$/i.test(
                String(originalName || '').trim()
            )
        );
    }

    function isDogSupportUnitCheckbox(
        input
    ) {
        if (!input) return false;

        // MissionChief UK Dog Support Unit vehicle type.
        // Type ID matching is authoritative and survives custom vehicle names.
        if (
            getVehicleTypeIdentifiers(
                input
            ).includes('12')
        ) {
            return true;
        }

        return getExtendedVehicleValues(
            input
        ).some(value => {
            const cleaned =
                normaliseSartecDisplayedName(
                    value
                );

            return (
                value === 'dog support unit' ||
                value === 'dog support units' ||
                value === 'dog support unit (dsu)' ||
                value === 'dog support units (dsu)' ||
                value === 'dog support units (dsus)' ||
                value === 'police dsu' ||
                value === 'dsu' ||
                /^Dog\s+Support\s+Unit(?:s)?(?:\s*\(\s*DSUs?\s*\))?\b/i.test(
                    cleaned
                ) ||
                /^Police\s+DSU\b/i.test(
                    cleaned
                ) ||
                /^DSU\b/i.test(
                    cleaned
                )
            );
        });
    }

    function isFireOperationalSupportRequirement(originalName, mappedName) {
        const raw = normaliseVehicleText(originalName);
        const mapped = normaliseVehicleText(mappedName);
        return mapped === 'osu' || mapped === 'operational support unit' ||
            /\b(?:basus?|breathing apparatus support (?:units?|vehicles?)|welfare(?: units?| vehicles?)?|hazmat(?: units?)?|cbrn vehicles?|fire operational support units?)\b/i.test(raw);
    }

    function isFireOperationalSupportUnitCheckbox(input) {
        if (!input) return false;
        const ids = getVehicleTypeIdentifiers(input);
        if (ids.length > 0) return ids.includes('39');

        // Name fallback is used only when MissionChief exposes no type ID.
        // Any known non-39 type, including type-7 HazMat Units, type-29/115
        // Welfare Vehicles and type-86 SAR Operational Support Vans, fails closed.
        return getExtendedVehicleValues(input).some(value => {
            const cleaned = normaliseVehicleText(value);
            return cleaned === 'operational support unit' || cleaned === 'operational support units' ||
                cleaned === 'osu' || cleaned === 'osus' || /\bosu\b/i.test(cleaned);
        });
    }

    function isOperationalSupportOrSarVehicleRequirement(
        originalName,
        mappedName
    ) {
        const raw = normaliseVehicleText(originalName);
        const mapped = normaliseVehicleText(mappedName);

        return (
            mapped === 'operational support van' ||
            raw === 'operational support van' ||
            raw === 'operational support vans' ||
            (
                !raw.includes('operational support unit') &&
                /\boperational support(?: vans?| vehicles?)?\b.*\bor\b.*\b(?:personal )?sar vehicles?\b/i.test(raw)
            )
        );
    }

    function isOperationalSupportVanCheckbox(input) {
        if (!input) return false;

        // MissionChief UK Operational Support Van type 86. This cannot collide
        // with the Fire Operational Support Unit, which is type 39.
        const typeIdentifiers = getVehicleTypeIdentifiers(input);
        if (typeIdentifiers.includes('86')) {
            return true;
        }
        if (typeIdentifiers.includes('39')) {
            return false;
        }

        return getExtendedVehicleValues(input).some(value => {
            const cleaned = normaliseVehicleText(value);
            return (
                cleaned === 'operational support van' ||
                cleaned === 'operational support vans' ||
                cleaned === 'osv' ||
                cleaned === 'osvs'
            );
        });
    }

    function getVehicleMatchCandidates(originalName, mappedName) {
        const raw = String(originalName || '').replace(/\s+/g, ' ').trim();
        const mapped = String(mappedName || '').replace(/\s+/g, ' ').trim();
        const cacheKey = `${raw.toLowerCase()}|${mapped.toLowerCase()}`;
        const cached = mfVehicleMatchCandidateCache.get(cacheKey);

        if (cached) return cached;

        const candidates = new Set([raw, mapped]);

        const add = value => {
            if (value) candidates.add(String(value).replace(/\s+/g, ' ').trim());
        };

        const lowerMapped = mapped.toLowerCase();
        const lowerRaw = raw.toLowerCase();

        if (lowerMapped.includes('fire engine') || lowerRaw.includes('pump') || lowerRaw.includes('rescue support')) {
            add('Fire Engine');
            add('Pump');
            add('Pumps');
            add('Rescue Pump');
            add('Rescue Support Unit');
            add('Rescue Support Vehicle');
        }

        if (lowerMapped === 'police atc' || lowerRaw.includes('traffic car')) {
            add('Traffic Car');
            add('Traffic Cars');
            add('Police ATC');
        }

        if (lowerMapped === 'police car' || lowerRaw.includes('police car')) {
            add('Police Car');
            add('Police Cars');
        }

        if (
            isAtvCarrierRequirement(
                originalName,
                mappedName
            )
        ) {
            add('ATV');
            add('ATV Carrier');
            add('ATV Carriers');
            add('ATC Carrier');
            add('ATC Carriers');
        }

        if (lowerMapped === 'police dsu' || lowerRaw.includes('dog support')) {
            add('Dog Support Unit (DSU)');
            add('Dog Support Units (DSU)');
            add('Dog Support Units (DSUs)');
            add('Police DSU');
            add('DSU');
        }

        const policeAirMode =
            getPoliceAirRequirementMode(
                originalName,
                mappedName
            );

        if (
            policeAirMode === 'flexible' ||
            policeAirMode === 'helicopter'
        ) {
            add('Police Helicopter');
            add('Police Helicopters');
            add('Policehelicopter');
            add('Policehelicopters');
        }

        if (
            policeAirMode === 'flexible' ||
            policeAirMode === 'drone'
        ) {
            add('Police Drone');
            add('Police Drones');
            add('Drone Vehicle(Police Station)');
            add('Drone Vehicle (Police Station)');
        }

        if (lowerMapped === 'welfare vehicle' || lowerRaw.includes('welfare vehicle')) {
            add('Welfare Vehicle');
            add('Welfare Vehicles');
        }

        if (
            isIccuOrAmbulanceControlRequirement(
                originalName,
                mappedName
            )
        ) {
            add('ICCU');
            add('ICCUs');
            add('Incident Command and Control Unit');
            add('Incident Command and Control Units');
            add('Ambulance Control Unit');
            add('Ambulance Control Units');
            add('ACU');
            add('ACUs');
        }

        if (
            lowerMapped === 'operational support van' ||
            lowerRaw.includes('operational support van') ||
            lowerRaw.includes('personal sar vehicle')
        ) {
            add('Operational Support Van');
            add('Operational Support Vans');
            add('OSV');
            add('OSVs');
        }

        if (
            lowerMapped === 'alb' ||
            lowerMapped === 'abl' ||
            lowerRaw.includes('seagoing vessel') ||
            lowerRaw.includes('all-weather lifeboat') ||
            lowerRaw.includes('all weather lifeboat')
        ) {
            add('ALB');
            add('ALBs');
            add('All-weather Lifeboat');
            add('All Weather Lifeboat');
            add('Seagoing Vessel');
            add('Seagoing Vessels');
            add('ABL');
            add('ABLs');
        }

        if (lowerMapped === 'ilb' || lowerRaw.includes('ilb')) {
            add('ILB');
            add('ILBs');
        }

        if (isRrvRequirement(originalName, mappedName)) {
            add('RRV');
            add('RRVs');
            add('Specialist Paramedic RRV');
            add('Specialist Paramedic RRVs');
            add('Rapid Response Vehicle');
            add('Rapid Response Vehicles');
        }

        if (isRivRequirement(originalName, mappedName)) {
            add('RIV');
            add('RIVs');
            add('Rapid Intervention Vehicle');
            add('Rapid Intervention Vehicles');
        }

        let result;

        // Ambulance Officer must never fall through to normal Ambulance matching.
        if (lowerMapped.includes('ambulance officer') || lowerRaw.includes('ambulance officer')) {
            result = ['ambulance officer', 'ambulance officers'];
        } else {
            if (
                lowerMapped === 'ambulance x 01' ||
                lowerMapped === 'ambulance' ||
                lowerMapped === 'ambulances' ||
                /^ambulances?$/i.test(raw)
            ) {
                add('Ambulance');
                add('Ambulances');
                add('Ambulance x 01');
            }

            result = Array.from(candidates)
                .filter(Boolean)
                .map(normaliseVehicleText);
        }

        if (mfVehicleMatchCandidateCache.size >= MF_VEHICLE_MATCH_CACHE_LIMIT) {
            mfVehicleMatchCandidateCache.clear();
        }

        mfVehicleMatchCandidateCache.set(cacheKey, result);
        return result;
    }

    function invalidateVehicleCheckboxCache() {
        mfVehicleCheckboxCache = {
            expiresAt: 0,
            nodes: []
        };

        // Vehicle rows are replaced during Load Missing and mission changes.
        // WeakMaps avoid retaining detached DOM nodes; resetting them also
        // handles MissionChief reusing a row with changed attributes.
        mfCheckboxVehicleValueCache = new WeakMap();
        mfExtendedVehicleValueCache = new WeakMap();
        mfSartecDisplayedValueCache = new WeakMap();
        mfVehicleTypeIdentifierCache = new WeakMap();
        mfVehicleArrivalMetricCache = new WeakMap();
    }

    function getVehicleCheckboxSnapshot(forceRefresh = false) {
        const now = Date.now();
        const cachedNodes = mfVehicleCheckboxCache.nodes;
        const firstNode = cachedNodes[0];
        const lastNode = cachedNodes[cachedNodes.length - 1];
        const cacheStillConnected =
            cachedNodes.length === 0 ||
            (
                firstNode?.isConnected !== false &&
                lastNode?.isConnected !== false
            );

        if (
            !forceRefresh &&
            now < mfVehicleCheckboxCache.expiresAt &&
            cacheStillConnected
        ) {
            return cachedNodes;
        }

        const nodes = Array.from(
            document.querySelectorAll('input.vehicle_checkbox')
        );

        mfVehicleCheckboxCache = {
            expiresAt: now + (nodes.length ? 500 : 120),
            nodes
        };

        return nodes;
    }

    function getCheckboxVehicleValues(input) {
        if (!input) return [];

        const cached = mfCheckboxVehicleValueCache.get(input);
        if (cached) return cached;

        const row = input.closest('tr');
        const values = [
            input.getAttribute('vehicle_caption'),
            input.getAttribute('vehicle_type_caption'),
            input.getAttribute('search_attribute'),
            input.getAttribute('vehicle_type'),
            row?.getAttribute('vehicle_caption'),
            row?.getAttribute('vehicle_type_caption'),
            row?.getAttribute('vehicle_type'),
            row?.querySelector('td:nth-child(2)')?.innerText
        ]
        .filter(Boolean)
        .map(normaliseVehicleText);

        mfCheckboxVehicleValueCache.set(input, values);
        return values;
    }

    function getExtendedVehicleValues(input) {
        if (!input) return [];

        const cached = mfExtendedVehicleValueCache.get(input);
        if (cached) return cached;

        const row = input.closest && input.closest('tr');
        const labelById = input.id
            ? document.getElementById(`label_${input.id}`)
            : null;

        const rowLabel = row && input.id
            ? Array.from(row.querySelectorAll('label[for]')).find(
                label => label.htmlFor === input.id
            )
            : null;

        const values = [
            ...getCheckboxVehicleValues(input),
            labelById?.textContent,
            labelById?.innerText,
            rowLabel?.textContent,
            rowLabel?.innerText,
            row?.querySelector('td[vehicle_type_id]')?.innerText
        ]
            .filter(Boolean)
            .map(normaliseVehicleText);

        mfExtendedVehicleValueCache.set(input, values);
        return values;
    }

    function isAmbulanceTransportRequest(originalName, mappedName) {
        const raw = normaliseVehicleText(originalName);
        const mapped = normaliseVehicleText(mappedName);

        if (raw.includes('ambulance officer') || mapped.includes('ambulance officer')) {
            return false;
        }

        return mapped === 'ambulance x 01'
            || mapped === 'ambulance'
            || mapped === 'ambulances'
            || raw === 'ambulance'
            || raw === 'ambulances'
            || raw === 'ambulance x 01';
    }

    function vehicleValuesMatchCandidates(values, candidates, strictExactOnly) {
        if (strictExactOnly) {
            return values.some(value => candidates.some(candidate => value === candidate));
        }

        return values.some(value => candidates.some(candidate => value === candidate || value.includes(candidate)));
    }

    function isVehicleElementAlreadySelected(element) {
        if (!element) return false;
        if (element.matches && element.matches('input.vehicle_checkbox')) return element.checked;
        const row = element.closest && element.closest('tr');
        const checkbox = row && row.querySelector('input.vehicle_checkbox');
        return checkbox ? checkbox.checked : false;
    }

    function clickVehicleElement(element) {
        if (!element) return false;

        if (element.matches && element.matches('input.vehicle_checkbox')) {
            if (!element.checked) {
                element.click();
            }
            return true;
        }

        element.click();
        return true;
    }

    function sortVehicleCheckboxesByBestArrival(matches) {
        const getMetrics = input => {
            const now = Date.now();
            const cached = mfVehicleArrivalMetricCache.get(input);

            if (cached && now < cached.expiresAt) {
                return cached;
            }

            const row = input?.closest?.('tr');
            const metrics = {
                delay: parseFloat(
                    row?.getAttribute('data-sortvalue') ||
                    row?.getAttribute('timevalue') ||
                    '999999'
                ),
                distance: parseFloat(
                    row?.getAttribute('data-distance') ||
                    '999999'
                ),
                expiresAt: now + 500
            };

            mfVehicleArrivalMetricCache.set(input, metrics);
            return metrics;
        };

        matches.sort((a, b) => {
            const metricsA = getMetrics(a);
            const metricsB = getMetrics(b);
            return (
                metricsA.delay - metricsB.delay ||
                metricsA.distance - metricsB.distance
            );
        });

        return matches;
    }

    function getAllMatchingVehicleCheckboxes(originalName, mappedName, includeChecked) {
        // BASU, Welfare and HazMat share the same selected exact type-39 Fire OSU.
        if (isFireOperationalSupportRequirement(originalName, mappedName)) {
            return sortVehicleCheckboxesByBestArrival(getVehicleCheckboxSnapshot().filter(input => {
                if (input.disabled) return false;
                if (!includeChecked && input.checked) return false;
                return isFireOperationalSupportUnitCheckbox(input);
            }));
        }
        const candidates = getVehicleMatchCandidates(originalName, mappedName);
        const strictExactOnly = isAmbulanceTransportRequest(originalName, mappedName);
        const sartecPrefixOnly = isSartecRequirement(
            originalName,
            mappedName
        );

        const rrvTypeOnly =
            isRrvRequirement(
                originalName,
                mappedName
            );

        const rivTypeOnly =
            isRivRequirement(
                originalName,
                mappedName
            );

        const rivOrMajorFoamTenderPreferred =
            isRivOrMajorFoamTenderRequirement(
                originalName,
                mappedName
            );

        const policeAirMode =
            getPoliceAirRequirementMode(
                originalName,
                mappedName
            );

        const policeCarOnly =
            isPoliceCarRequirement(
                originalName,
                mappedName
            );

        const atvCarrierOnly =
            isAtvCarrierRequirement(
                originalName,
                mappedName
            );

        const seagoingVesselOnly =
            isSeagoingVesselRequirement(
                originalName,
                mappedName
            );

        const dogSupportOnly =
            isDogSupportUnitRequirement(
                originalName,
                mappedName
            );

        const operationalSupportOnly =
            isOperationalSupportOrSarVehicleRequirement(
                originalName,
                mappedName
            );

        const generic4x4Only =
            isGeneric4x4VehicleRequirement(
                originalName,
                mappedName
            );

        const mountainRescue4x4Preferred =
            isMountainRescueOrSar4x4Requirement(
                originalName,
                mappedName
            );

        const iccuPreferred =
            isIccuOrAmbulanceControlRequirement(
                originalName,
                mappedName
            );


        if (seagoingVesselOnly) {
            return sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) return false;
                    if (!includeChecked && input.checked) return false;
                    return isSeagoingVesselCheckbox(input);
                })
            );
        }


        if (
            rivOrMajorFoamTenderPreferred
        ) {
            const eligible =
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) {
                        return false;
                    }

                    if (
                        !includeChecked &&
                        input.checked
                    ) {
                        return false;
                    }

                    return (
                        isRivVehicleCheckbox(
                            input
                        ) ||
                        isMajorFoamTenderVehicleCheckbox(
                            input
                        )
                    );
                });

            const rivMatches =
                sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isRivVehicleCheckbox
                    )
                );

            if (
                rivMatches.length >
                0
            ) {
                return rivMatches;
            }

            return sortVehicleCheckboxesByBestArrival(
                eligible.filter(
                    isMajorFoamTenderVehicleCheckbox
                )
            );
        }

        if (atvCarrierOnly) {
            return sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) {
                        return false;
                    }

                    if (
                        !includeChecked &&
                        input.checked
                    ) {
                        return false;
                    }

                    return isAtvCarrierCheckbox(
                        input
                    );
                })
            );
        }

        if (dogSupportOnly) {
            return sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) {
                        return false;
                    }

                    if (
                        !includeChecked &&
                        input.checked
                    ) {
                        return false;
                    }

                    return isDogSupportUnitCheckbox(
                        input
                    );
                })
            );
        }

        if (operationalSupportOnly) {
            return sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) return false;
                    if (!includeChecked && input.checked) return false;
                    return isOperationalSupportVanCheckbox(input);
                })
            );
        }

        if (iccuPreferred) {
            const eligible =
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) {
                        return false;
                    }

                    if (
                        !includeChecked &&
                        input.checked
                    ) {
                        return false;
                    }

                    return (
                        isIccuVehicleCheckbox(
                            input
                        ) ||
                        isAmbulanceControlUnitCheckbox(
                            input
                        )
                    );
                });

            const iccuMatches =
                sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isIccuVehicleCheckbox
                    )
                );

            const ambulanceControlFallbackMatches =
                sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        input =>
                            !isIccuVehicleCheckbox(input) &&
                            isAmbulanceControlUnitCheckbox(input)
                    )
                );

            return [
                ...iccuMatches,
                ...ambulanceControlFallbackMatches
            ];
        }

        if (generic4x4Only) {
            return sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) {
                        return false;
                    }

                    if (
                        !includeChecked &&
                        input.checked
                    ) {
                        return false;
                    }

                    return isGeneric4x4VehicleCheckbox(
                        input
                    );
                })
            );
        }

        if (mountainRescue4x4Preferred) {
            const eligible =
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) {
                        return false;
                    }

                    if (
                        !includeChecked &&
                        input.checked
                    ) {
                        return false;
                    }

                    return (
                        isMountainRescue4x4Checkbox(
                            input
                        ) ||
                        isSar4x4Checkbox(
                            input
                        )
                    );
                });

            const mountainRescueMatches =
                sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isMountainRescue4x4Checkbox
                    )
                );

            const sarFallbackMatches =
                sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isSar4x4Checkbox
                    )
                );

            const orderedMatches = [
                ...mountainRescueMatches,
                ...sarFallbackMatches
            ];

            if (mfDebugEnabled) {
                debugLog(
                    'MOUNTAIN 4X4 PRIORITY',
                    `${originalName} -> ${mappedName} | Mountain Rescue 4x4 matches=${mountainRescueMatches.length} first | SAR 4x4 matches=${sarFallbackMatches.length} fallback | returned=${orderedMatches.length}`
                );
            }

            return orderedMatches;
        }

        if (policeAirMode) {
            const eligible =
                getVehicleCheckboxSnapshot().filter(input => {
                    if (input.disabled) {
                        return false;
                    }

                    if (
                        !includeChecked &&
                        input.checked
                    ) {
                        return false;
                    }

                    if (policeAirMode === 'helicopter') {
                        return isPoliceHelicopterCheckbox(input);
                    }

                    if (policeAirMode === 'drone') {
                        return isPoliceDroneCheckbox(input);
                    }

                    return (
                        isPoliceHelicopterCheckbox(input) ||
                        isPoliceDroneCheckbox(input)
                    );
                });

            if (policeAirMode === 'helicopter') {
                return sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isPoliceHelicopterCheckbox
                    )
                );
            }

            if (policeAirMode === 'drone') {
                return sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isPoliceDroneCheckbox
                    )
                );
            }

            const sortedDroneMatches =
                sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isPoliceDroneCheckbox
                    )
                );

            const sortedHelicopterMatches =
                sortVehicleCheckboxesByBestArrival(
                    eligible.filter(
                        isPoliceHelicopterCheckbox
                    )
                );

            // Flexible wording only: Drone first, Police Helicopter fallback.
            return [
                ...sortedDroneMatches,
                ...sortedHelicopterMatches
            ];
        }

        if (policeCarOnly) {
            const registry =
                readPersonnelTrainingRegistry();

            const ordinaryCandidates =
                sortVehicleCheckboxesByBestArrival(
                    getVehicleCheckboxSnapshot().filter(input => {
                        if (input.disabled) return false;
                        if (!includeChecked && input.checked) return false;

                        return isOrdinaryPoliceIrvCheckboxEligible(
                            input,
                            registry,
                            { allowUnknown: false }
                        );
                    })
                );

            return orderOrdinaryPoliceIrvCandidates(
                ordinaryCandidates,
                registry
            );
        }

        const matches = getVehicleCheckboxSnapshot().filter(input => {
            if (input.disabled) return false;
            if (!includeChecked && input.checked) return false;

            if (sartecPrefixOnly) {
                return isSartecVehicleCheckbox(
                    input
                );
            }

            if (rrvTypeOnly) {
                return isRrvVehicleCheckbox(
                    input
                );
            }

            if (rivTypeOnly) {
                return isRivVehicleCheckbox(
                    input
                );
            }

            if (policeCarOnly) {
                return isPoliceCarVehicleCheckbox(
                    input
                );
            }

            const values = getCheckboxVehicleValues(input);
            return vehicleValuesMatchCandidates(values, candidates, strictExactOnly);
        });

        if (mfDebugEnabled && strictExactOnly) {
            debugLog('AMBULANCE STRICT', `${originalName} -> ${mappedName} | exact-match boxes=${matches.length}`);
        }

        if (mfDebugEnabled && sartecPrefixOnly) {
            debugLog(
                'SARTEC PREFIX',
                `${originalName} -> ${mappedName} | displayed-name-prefix boxes=${matches.length}`
            );
        }

        if (
            mfDebugEnabled &&
            rrvTypeOnly
        ) {
            debugLog(
                'RRV STRICT',
                `${originalName} -> ${mappedName} | RRV type boxes=${matches.length}`
            );
        }

        if (
            mfDebugEnabled &&
            rivTypeOnly
        ) {
            debugLog(
                'RIV STRICT',
                `${originalName} -> ${mappedName} | RIV type boxes=${matches.length}`
            );
        }

        if (
            mfDebugEnabled &&
            policeCarOnly
        ) {
            debugLog(
                'POLICE CAR STRICT',
                `${originalName} -> ${mappedName} | Police Car/IRV type boxes=${matches.length}`
            );
        }

        return sortVehicleCheckboxesByBestArrival(matches);
    }

    function getMatchingVehicleCheckboxes(originalName, mappedName) {
        return getAllMatchingVehicleCheckboxes(originalName, mappedName, false);
    }

    function countSelectedMatchingVehicles(originalName, mappedName) {
        if (isFireOperationalSupportRequirement(originalName, mappedName)) {
            return getVehicleCheckboxSnapshot().filter(input =>
                input.checked && isFireOperationalSupportUnitCheckbox(input)).length;
        }
        const candidates = getVehicleMatchCandidates(originalName, mappedName);
        const strictExactOnly = isAmbulanceTransportRequest(originalName, mappedName);
        const sartecPrefixOnly = isSartecRequirement(originalName, mappedName);
        const rrvTypeOnly = isRrvRequirement(originalName, mappedName);
        const rivTypeOnly = isRivRequirement(originalName, mappedName);

        const rivOrMajorFoamTenderPreferred =
            isRivOrMajorFoamTenderRequirement(
                originalName,
                mappedName
            );
        const policeAirMode = getPoliceAirRequirementMode(originalName, mappedName);
        const policeCarOnly = isPoliceCarRequirement(originalName, mappedName);
        const atvCarrierOnly = isAtvCarrierRequirement(originalName, mappedName);
        const seagoingVesselOnly = isSeagoingVesselRequirement(originalName, mappedName);
        const dogSupportOnly = isDogSupportUnitRequirement(originalName, mappedName);
        const operationalSupportOnly =
            isOperationalSupportOrSarVehicleRequirement(
                originalName,
                mappedName
            );

        const generic4x4Only =
            isGeneric4x4VehicleRequirement(
                originalName,
                mappedName
            );

        const mountainRescue4x4Preferred =
            isMountainRescueOrSar4x4Requirement(
                originalName,
                mappedName
            );
        const iccuPreferred =
            isIccuOrAmbulanceControlRequirement(
                originalName,
                mappedName
            );

        const ordinaryPoliceRegistry =
            policeCarOnly
                ? readPersonnelTrainingRegistry()
                : null;


        if (
            rivOrMajorFoamTenderPreferred
        ) {
            const selected =
                getVehicleCheckboxSnapshot().filter(
                    input =>
                        input.checked
                );

            const selectedRivs =
                selected.filter(
                    isRivVehicleCheckbox
                ).length;

            if (
                selectedRivs >
                0
            ) {
                return selectedRivs;
            }

            return selected.filter(
                isMajorFoamTenderVehicleCheckbox
            ).length;
        }

        let count = 0;

        for (const input of getVehicleCheckboxSnapshot()) {
            // A vehicle that is already checked still counts toward the
            // requirement even when MissionChief disables its checkbox after
            // selection. V10.6.48 skipped disabled checked boxes, which made a
            // successfully selected vehicle look missing during verification.
            if (!input.checked) continue;

            let matches = false;

            if (seagoingVesselOnly) {
                matches = isSeagoingVesselCheckbox(
                    input
                );
            } else if (atvCarrierOnly) {
                matches = isAtvCarrierCheckbox(
                    input
                );
            } else if (dogSupportOnly) {
                matches = isDogSupportUnitCheckbox(
                    input
                );
            } else if (operationalSupportOnly) {
                matches = isOperationalSupportVanCheckbox(input);
            } else if (iccuPreferred) {
                matches =
                    isIccuVehicleCheckbox(input) ||
                    isAmbulanceControlUnitCheckbox(input);
            } else if (generic4x4Only) {
                matches = isGeneric4x4VehicleCheckbox(input);
            } else if (mountainRescue4x4Preferred) {
                matches =
                    isMountainRescue4x4Checkbox(input) ||
                    isSar4x4Checkbox(input);
            } else if (policeAirMode === 'helicopter') {
                matches = isPoliceHelicopterCheckbox(input);
            } else if (policeAirMode === 'drone') {
                matches = isPoliceDroneCheckbox(input);
            } else if (policeAirMode === 'flexible') {
                matches =
                    isPoliceHelicopterCheckbox(input) ||
                    isPoliceDroneCheckbox(input);
            } else if (sartecPrefixOnly) {
                matches = isSartecVehicleCheckbox(input);
            } else if (rrvTypeOnly) {
                matches = isRrvVehicleCheckbox(input);
            } else if (rivTypeOnly) {
                matches = isRivVehicleCheckbox(input);
            } else if (policeCarOnly) {
                matches =
                    isOrdinaryPoliceIrvCheckboxEligible(
                        input,
                        ordinaryPoliceRegistry,
                        { allowUnknown: false }
                    );
            } else {
                matches = vehicleValuesMatchCandidates(
                    getCheckboxVehicleValues(input),
                    candidates,
                    strictExactOnly
                );
            }

            if (matches) count += 1;
        }

        return count;
    }

    function refreshVehicleRequirementCounters() {
        // V9.2.1: DISPLAY ONLY. This updates the panel counters from the current ticked checkboxes.
        // It must not decide what to send and must not trigger any selections.
        vehicleLoadState.rows.forEach(row => {
            const required = Number(row.required || 0);
            const selected = countSelectedMatchingVehicles(row.originalName, row.mappedName);
            row.selected = Math.min(selected, required);
        });
    }

    function findUnitButton(mappedName, originalName) {
        if (isFireOperationalSupportRequirement(originalName, mappedName)) {
            return sortVehicleCheckboxesByBestArrival(getVehicleCheckboxSnapshot().filter(input =>
                !input.disabled && !input.checked && isFireOperationalSupportUnitCheckbox(input)))[0] || null;
        }
        const requestedName =
            originalName ||
            mappedName;


        if (
            isSeagoingVesselRequirement(
                requestedName,
                mappedName
            )
        ) {
            return getVehicleCheckboxSnapshot(true).find(input => {
                return (
                    !input.disabled &&
                    !input.checked &&
                    isSeagoingVesselCheckbox(input)
                );
            }) || null;
        }

        if (
            isDogSupportUnitRequirement(
                requestedName,
                mappedName
            )
        ) {
            // Never use the AAO/ARR group button as proof of a DSU selection.
            // It previously returned a successful click while no matching
            // vehicle checkbox was checked, causing the repeated false
            // "Final missing units: Dog Support Units" popup.
            return getVehicleCheckboxSnapshot(
                true
            ).find(input => {
                return (
                    !input.disabled &&
                    !input.checked &&
                    isDogSupportUnitCheckbox(
                        input
                    )
                );
            }) || null;
        }

        if (
            isOperationalSupportOrSarVehicleRequirement(
                requestedName,
                mappedName
            )
        ) {
            return sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(input => (
                    !input.disabled &&
                    !input.checked &&
                    isOperationalSupportVanCheckbox(input)
                ))
            )[0] || null;
        }

        if (
            isIccuOrAmbulanceControlRequirement(
                requestedName,
                mappedName
            )
        ) {
            const available =
                getVehicleCheckboxSnapshot().filter(input => {
                    return (
                        !input.disabled &&
                        !input.checked
                    );
                });

            const iccuCheckbox =
                available.find(
                    isIccuVehicleCheckbox
                );

            if (iccuCheckbox) {
                return iccuCheckbox;
            }

            const iccuButton =
                Array.from(
                    document.querySelectorAll(
                        'a[search_attribute]'
                    )
                ).find(anchor => {
                    const value =
                        normaliseVehicleText(
                            anchor.getAttribute(
                                'search_attribute'
                            )
                        );

                    return (
                        value === 'iccu' ||
                        value === 'iccus' ||
                        value.includes(
                            'incident command and control unit'
                        ) ||
                        /(?:^|\b)iccu(?:s)?(?:\b|$)/i.test(value)
                    );
                });

            if (iccuButton) {
                return iccuButton;
            }

            const ambulanceControlCheckbox =
                available.find(
                    isAmbulanceControlUnitCheckbox
                );

            if (ambulanceControlCheckbox) {
                return ambulanceControlCheckbox;
            }

            return Array.from(
                document.querySelectorAll(
                    'a[search_attribute]'
                )
            ).find(anchor => {
                const value =
                    normaliseVehicleText(
                        anchor.getAttribute(
                            'search_attribute'
                        )
                    );

                return (
                    value === 'acu' ||
                    value === 'acus' ||
                    value.includes(
                        'ambulance control unit'
                    ) ||
                    /(?:^|\b)acu(?:s)?(?:\b|$)/i.test(value)
                );
            }) || null;
        }

        if (
            isGeneric4x4VehicleRequirement(
                requestedName,
                mappedName
            )
        ) {
            return sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(input => {
                    return (
                        !input.disabled &&
                        !input.checked &&
                        isGeneric4x4VehicleCheckbox(
                            input
                        )
                    );
                })
            )[0] || null;
        }

        if (
            isMountainRescueOrSar4x4Requirement(
                requestedName,
                mappedName
            )
        ) {
            const available =
                getVehicleCheckboxSnapshot().filter(input => {
                    return (
                        !input.disabled &&
                        !input.checked
                    );
                });

            const mountainRescueMatches =
                sortVehicleCheckboxesByBestArrival(
                    available.filter(
                        isMountainRescue4x4Checkbox
                    )
                );

            if (mountainRescueMatches.length > 0) {
                return mountainRescueMatches[0];
            }

            const sarMatches =
                sortVehicleCheckboxesByBestArrival(
                    available.filter(
                        isSar4x4Checkbox
                    )
                );

            // Do not fall back to an AAO/ARR group button. A group-button click
            // cannot be verified as a selected vehicle and caused the false
            // "Final missing units: 4x4 Vehicles" popup.
            return sarMatches[0] || null;
        }

        if (
            isSartecRequirement(
                requestedName,
                mappedName
            )
        ) {
            // SARTEC must only come from the actual available-vehicle
            // checkbox list and must begin the displayed vehicle name.
            return getVehicleCheckboxSnapshot().find(input => {
                return (
                    !input.disabled &&
                    !input.checked &&
                    isSartecVehicleCheckbox(
                        input
                    )
                );
            }) || null;
        }

        if (
            isRrvRequirement(
                requestedName,
                mappedName
            )
        ) {
            return getVehicleCheckboxSnapshot().find(input => {
                return (
                    !input.disabled &&
                    !input.checked &&
                    isRrvVehicleCheckbox(
                        input
                    )
                );
            }) || null;
        }

        if (
            isRivRequirement(
                requestedName,
                mappedName
            )
        ) {
            return getVehicleCheckboxSnapshot().find(input => {
                return (
                    !input.disabled &&
                    !input.checked &&
                    isRivVehicleCheckbox(
                        input
                    )
                );
            }) || null;
        }

        const policeAirMode =
            getPoliceAirRequirementMode(
                requestedName,
                mappedName
            );

        if (policeAirMode) {
            const eligible =
                getVehicleCheckboxSnapshot().filter(input => {
                    return (
                        !input.disabled &&
                        !input.checked
                    );
                });

            if (policeAirMode === 'helicopter') {
                return eligible.find(
                    isPoliceHelicopterCheckbox
                ) || null;
            }

            if (policeAirMode === 'drone') {
                return eligible.find(
                    isPoliceDroneCheckbox
                ) || null;
            }

            return (
                eligible.find(
                    isPoliceDroneCheckbox
                ) ||
                eligible.find(
                    isPoliceHelicopterCheckbox
                ) ||
                null
            );
        }

        if (
            isPoliceCarRequirement(
                requestedName,
                mappedName
            )
        ) {
            return getAllMatchingVehicleCheckboxes(
                requestedName,
                mappedName,
                false
            )[0] || null;
        }

        const candidates = getVehicleMatchCandidates(requestedName, mappedName);

        const strictExactOnly = isAmbulanceTransportRequest(requestedName, mappedName);

        const checkbox = getVehicleCheckboxSnapshot().find(input => {
            if (input.disabled || input.checked) return false;
            const values = getCheckboxVehicleValues(input);
            return vehicleValuesMatchCandidates(values, candidates, strictExactOnly);
        });

        if (checkbox) return checkbox;

        const button = Array.from(document.querySelectorAll('a[search_attribute]')).find(anchor => {
            const value = normaliseVehicleText(anchor.getAttribute('search_attribute'));
            return candidates.some(candidate => value === candidate || value.includes(candidate));
        });

        return button || null;
    }

    function injectStyles() {
        if (document.getElementById('mission-finder-2026-styles')) return;

        const style = document.createElement('style');
        style.id = 'mission-finder-2026-styles';
        style.textContent = `
            #mission-finder-wrapper {
                position: fixed;
                z-index: 999999;
                display: flex;
                gap: 8px;
                align-items: flex-start;
                font-family: Arial, Helvetica, sans-serif;
            }

            .mf2026-panel {
                width: 270px;
                min-height: 0;
                padding: 8px;
                background: rgba(0, 0, 0, 0.88);
                color: white;
                font-size: 13px;
                border: 2px solid white;
                border-radius: 8px;
                box-sizing: border-box;
                display: flex;
                flex-direction: column;
                gap: 7px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.35);
            }

            .mf2026-header {
                font-size: 15px;
                font-weight: bold;
                text-align: center;
                background: #555;
                padding: 6px;
                border-radius: 4px;
            }

            .mf2026-drag {
                cursor: move;
            }

            .mf2026-box {
                background: #444;
                padding: 7px;
                border-radius: 5px;
            }

            #status-box {
                min-height: 44px;
                line-height: 1.35;
                overflow-wrap: break-word;
            }

            .mf2026-button {
                padding: 7px;
                border: none;
                border-radius: 5px;
                cursor: pointer;
                font-weight: bold;
            }

            .mf2026-section-title {
                font-size: 13px;
                font-weight: bold;
                margin-bottom: 5px;
                color: #ddd;
            }

            .mf2026-row {
                display: flex;
                justify-content: space-between;
                gap: 8px;
                padding: 4px 0;
                border-bottom: 1px solid rgba(255,255,255,0.08);
            }

            .mf2026-row:last-child {
                border-bottom: none;
            }

            .mf2026-name {
                flex: 1;
            }

            .mf2026-count {
                white-space: nowrap;
                font-weight: bold;
            }

            .mf2026-good {
                color: #42ff75;
            }

            .mf2026-bad {
                color: #ff6666;
            }

            .mf2026-warn {
                color: #ffd166;
            }

            .mf2026-small {
                font-size: 12px;
                color: #ccc;
            }

            .mf2026-progress-wrap {
                background: #222;
                border-radius: 6px;
                overflow: hidden;
                height: 10px;
            }

            .mf2026-progress-bar {
                height: 10px;
                width: 0%;
                background: #42ff75;
                transition: width 0.25s ease;
            }

            #vehicle-load-list-content {
                max-height: 210px;
                overflow-y: auto;
                padding-right: 4px;
            }

            #mf-mission-ready-delay-input {
                width: 100%;
                color: black;
                padding: 4px;
                border-radius: 4px;
                border: none;
                box-sizing: border-box;
            }

            .mf2026-checkbox-row {
                display: flex;
                align-items: center;
                gap: 8px;
                cursor: pointer;
                user-select: none;
            }

            .mf2026-checkbox-row input {
                width: 17px;
                height: 17px;
                margin: 0;
                flex: 0 0 auto;
            }

            #session-panel-content {
                max-height: 180px;
                overflow-y: auto;
                padding-right: 4px;
            }

            .mf2026-stat-grid {
                display: grid;
                grid-template-columns: 1fr auto;
                gap: 4px 8px;
                font-size: 12px;
                color: #ccc;
            }

            .mf2026-stat-grid strong {
                color: white;
            }

            .mf2026-log-row {
                display: grid;
                grid-template-columns: 1fr auto;
                gap: 8px;
                padding: 4px 0;
                border-bottom: 1px solid rgba(255,255,255,0.08);
                font-size: 12px;
            }

            .mf2026-log-row:last-child {
                border-bottom: none;
            }

            .mf2026-log-main {
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }

            .mf2026-log-value {
                white-space: nowrap;
                font-weight: bold;
            }


            #control-panel {
                width: 260px;
            }

            #vehicle-load-list-box {
                width: 300px;
            }

            #control-panel.mf2026-control-collapsed {
                width: 44px;
                min-height: 0;
                padding: 6px;
                overflow: hidden;
            }

            #control-panel.mf2026-control-collapsed .mf-control-body {
                display: none;
            }

            #control-panel.mf2026-control-collapsed .mf2026-header {
                writing-mode: vertical-rl;
                text-orientation: mixed;
                min-height: 120px;
                padding: 8px 4px;
                cursor: pointer;
            }

            .mf2026-control-header-row {
                display: flex;
                gap: 6px;
                align-items: center;
            }

            .mf2026-control-header-row .mf2026-header {
                flex: 1;
            }

            #mf-control-centre,
            #mf-control-minimize {
                width: 34px;
                padding: 6px 0;
                background: #6c757d;
                color: white;
                flex: 0 0 34px;
            }

            #mf-control-centre {
                background: #0d6efd;
            }


            #vehicle-load-list-box.mf2026-load-collapsed {
                width: 44px;
                min-height: 0;
                padding: 6px;
                overflow: hidden;
            }

            #vehicle-load-list-box.mf2026-load-collapsed .mf-load-body {
                display: none;
            }

            #vehicle-load-list-box.mf2026-load-collapsed .mf2026-header {
                writing-mode: vertical-rl;
                text-orientation: mixed;
                min-height: 130px;
                padding: 8px 4px;
                cursor: pointer;
            }

            .mf2026-load-header-row {
                display: flex;
                gap: 6px;
                align-items: center;
            }

            .mf2026-load-header-row .mf2026-header {
                flex: 1;
            }

            #mf-load-minimize {
                width: 34px;
                padding: 6px 0;
                background: #6c757d;
                color: white;
            }

            .mf2026-button-row {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 6px;
            }

            #mission-finder-wrapper.mf2026-ios-safari {
                top: calc(8px + env(safe-area-inset-top, 0px));
                right: calc(8px + env(safe-area-inset-right, 0px));
                left: calc(8px + env(safe-area-inset-left, 0px));
                width: auto;
                max-width: none;
                max-height: calc(
                    100vh
                    - 16px
                    - env(safe-area-inset-top, 0px)
                    - env(safe-area-inset-bottom, 0px)
                );
                display: flex;
                flex-direction: column;
                align-items: stretch;
                gap: 6px;
                overflow-x: hidden;
                overflow-y: auto;
                overscroll-behavior: contain;
                -webkit-overflow-scrolling: touch;
                -webkit-transform: translateZ(0);
                box-sizing: border-box;
            }

            @supports (height: 100dvh) {
                #mission-finder-wrapper.mf2026-ios-safari {
                    max-height: calc(
                        100dvh
                        - 16px
                        - env(safe-area-inset-top, 0px)
                        - env(safe-area-inset-bottom, 0px)
                    );
                }
            }

            #mission-finder-wrapper.mf2026-ios-safari .mf2026-panel,
            #mission-finder-wrapper.mf2026-ios-safari #control-panel,
            #mission-finder-wrapper.mf2026-ios-safari #vehicle-load-list-box {
                width: 100%;
                max-width: none;
                flex: 0 0 auto;
            }

            #mission-finder-wrapper.mf2026-ios-safari .mf2026-header {
                min-height: 42px;
                display: flex;
                align-items: center;
                justify-content: center;
                box-sizing: border-box;
            }

            #mission-finder-wrapper.mf2026-ios-safari .mf2026-drag {
                cursor: grab;
                touch-action: none;
                -webkit-user-select: none;
                user-select: none;
            }

            #mission-finder-wrapper.mf2026-ios-safari .mf2026-drag:active {
                cursor: grabbing;
            }

            #mission-finder-wrapper.mf2026-ios-safari .mf-control-body,
            #mission-finder-wrapper.mf2026-ios-safari .mf-load-body,
            #mission-finder-wrapper.mf2026-ios-safari #vehicle-load-list-content,
            #mission-finder-wrapper.mf2026-ios-safari #session-panel-content {
                -webkit-overflow-scrolling: touch;
            }

            #mission-finder-wrapper.mf2026-ios-safari .mf2026-button {
                min-height: 42px;
                font-size: 14px;
                touch-action: manipulation;
            }

            #mission-finder-wrapper.mf2026-ios-safari input,
            #mission-finder-wrapper.mf2026-ios-safari select {
                min-height: 38px;
                font-size: 16px;
            }

            #mission-finder-wrapper.mf2026-ios-safari #mf-control-position-box,
            #mission-finder-wrapper.mf2026-ios-safari #mf-control-centre {
                display: none;
            }

            #mission-finder-wrapper.mf2026-ios-safari #mf-control-minimize {
                width: 44px;
                flex: 0 0 44px;
                padding: 6px 0;
                font-size: 20px;
                line-height: 1;
            }

            #mission-finder-wrapper.mf2026-ios-safari
            #control-panel.mf2026-control-collapsed {
                width: 100%;
                min-height: 0;
                padding: 6px;
                overflow: hidden;
            }

            #mission-finder-wrapper.mf2026-ios-safari
            #control-panel.mf2026-control-collapsed
            .mf2026-control-header-row {
                width: 100%;
            }

            #mission-finder-wrapper.mf2026-ios-safari
            #control-panel.mf2026-control-collapsed
            .mf2026-header {
                writing-mode: horizontal-tb;
                text-orientation: mixed;
                min-height: 42px;
                padding: 8px 10px;
                justify-content: flex-start;
                text-align: left;
            }

            #mission-finder-wrapper.mf2026-ios-safari
            #vehicle-load-list-box.mf2026-load-collapsed {
                width: 100%;
                min-height: 0;
                padding: 6px;
                overflow: hidden;
            }

            #mission-finder-wrapper.mf2026-ios-safari
            #vehicle-load-list-box.mf2026-load-collapsed
            .mf2026-header {
                writing-mode: horizontal-tb;
                text-orientation: mixed;
                min-height: 42px;
                padding: 8px 10px;
                justify-content: flex-start;
                text-align: left;
            }
        `;
        document.head.appendChild(style);
    }

    function createControlPanel() {
        if (!isMissionPage()) return;

        if (!claimCurrentMissionExecutionOwnership('create control panel')) {
            document.getElementById('mission-finder-wrapper')?.remove();
            return;
        }

        cleanupDuplicatePanels();

        if (document.getElementById('mission-finder-wrapper')) return;

        injectStyles();

        const wrapper = document.createElement('div');
        wrapper.id = 'mission-finder-wrapper';

        const missionFinderIosSafari =
            isMissionFinderIosSafariWebsite();

        wrapper.classList.toggle(
            'mf2026-ios-safari',
            missionFinderIosSafari
        );

        const savedPanelLeft =
            localStorage.getItem(MF_PANEL_LEFT_KEY);

        const savedPanelTop =
            localStorage.getItem(MF_PANEL_TOP_KEY);

        if (!missionFinderIosSafari) {
            wrapper.style.left =
                mfKeepPanelPosition && savedPanelLeft
                    ? savedPanelLeft
                    : '20px';

            wrapper.style.top =
                mfKeepPanelPosition && savedPanelTop
                    ? savedPanelTop
                    : '20px';
        }

        wrapper.style.visibility = 'hidden';

        // Remove coordinates used by the older panel-position versions.
        localStorage.removeItem('panel-left');
        localStorage.removeItem('panel-top');

        const panel = document.createElement('div');
        panel.id = 'control-panel';
        panel.className = `mf2026-panel ${mfMissionControlCollapsed ? 'mf2026-control-collapsed' : ''}`;

        const controlHeaderRow = document.createElement('div');
        controlHeaderRow.className = 'mf2026-control-header-row';

        const dragHandle = document.createElement('div');
        dragHandle.id = 'mf-control-title';
        dragHandle.textContent = 'Mission Control';
        dragHandle.className = 'mf2026-header mf2026-drag';

        const controlCentreBtn = document.createElement('button');
        controlCentreBtn.id = 'mf-control-centre';
        controlCentreBtn.className = 'mf2026-button';
        controlCentreBtn.title = 'Move Mission Control back to the centre';
        controlCentreBtn.textContent = '◎';

        const controlMinimizeBtn = document.createElement('button');
        controlMinimizeBtn.id = 'mf-control-minimize';
        controlMinimizeBtn.className = 'mf2026-button';
        controlMinimizeBtn.type = 'button';

        controlHeaderRow.appendChild(dragHandle);
        controlHeaderRow.appendChild(controlCentreBtn);
        controlHeaderRow.appendChild(controlMinimizeBtn);
        panel.appendChild(controlHeaderRow);

        const controlBody = document.createElement('div');
        controlBody.className = 'mf-control-body';

        const statusBox = document.createElement('div');
        statusBox.id = 'status-box';
        statusBox.className = 'mf2026-box';
        statusBox.textContent = 'Ready to start...';
        controlBody.appendChild(statusBox);

        const positionBox = document.createElement('div');
        positionBox.id = 'mf-control-position-box';
        positionBox.className = 'mf2026-box';
        positionBox.innerHTML = `
            <div class="mf2026-section-title">Control Window Position</div>
            <label class="mf2026-checkbox-row">
                <input id="mf-keep-panel-position"
                       type="checkbox"
                       ${mfKeepPanelPosition ? 'checked' : ''}>
                <span>Keep my saved panel position</span>
            </label>
            <div class="mf2026-small" style="margin-top:5px;">
                Off = centre on every mission. On = remember where you drag it.
            </div>
        `;
        controlBody.appendChild(positionBox);

        const keepPanelPositionCheckbox =
            positionBox.querySelector('#mf-keep-panel-position');

        const delayBox = document.createElement('div');
        delayBox.className = 'mf2026-box';
        delayBox.innerHTML = `
            <div class="mf2026-section-title">Mission Ready Delay</div>
            <input id="mf-mission-ready-delay-input"
                   type="number"
                   min="500"
                   max="15000"
                   step="500"
                   value="${missionReadyDelayMs}">
            <div class="mf2026-small">
                Default 1000ms. Auto Mode uses readiness checks and skips duplicate loading waits.
            </div>
        `;
        controlBody.appendChild(delayBox);

        delayBox.querySelector('#mf-mission-ready-delay-input').addEventListener('change', function() {
            const value = parseInt(this.value, 10);
            missionReadyDelayMs = Number.isFinite(value) ? Math.max(500, Math.min(15000, value)) : DEFAULT_MISSION_READY_DELAY;
            this.value = missionReadyDelayMs;
            localStorage.setItem('mf_mission_ready_delay_ms', String(missionReadyDelayMs));
            updateStatusBox(`Mission Ready Delay set to ${missionReadyDelayMs}ms`);
        });

        const queueRestartBox = document.createElement('div');
        queueRestartBox.className = 'mf2026-box';
        queueRestartBox.innerHTML = `
            <div class="mf2026-section-title">V10 Queue Restart</div>
            <button id="mf-next-queue-restart-toggle"
                    class="mf2026-button"
                    style="width:100%;background:${mfQueueRestartEnabled ? '#198754' : '#6c757d'};color:white;margin-bottom:6px;">
                Queue Restart: ${mfQueueRestartEnabled ? 'On' : 'Off'}
            </button>
            <input id="mf-next-queue-restart-threshold"
                   type="number"
                   min="1"
                   max="999"
                   step="1"
                   value="${mfQueueRestartThreshold}"
                   style="width:100%;color:black;padding:4px;border-radius:4px;border:none;box-sizing:border-box;">
        `;
        controlBody.appendChild(queueRestartBox);

        const queueRestartToggle = queueRestartBox.querySelector('#mf-next-queue-restart-toggle');
        const queueRestartThresholdInput = queueRestartBox.querySelector('#mf-next-queue-restart-threshold');

        queueRestartToggle.addEventListener('click', function() {
            mfQueueRestartEnabled = !mfQueueRestartEnabled;
            localStorage.setItem('mf_next_queue_restart_enabled_v10', String(mfQueueRestartEnabled));
            queueRestartToggle.textContent = `Queue Restart: ${mfQueueRestartEnabled ? 'On' : 'Off'}`;
            queueRestartToggle.style.backgroundColor = mfQueueRestartEnabled ? '#198754' : '#6c757d';
            updateStatusBox(`Queue Restart ${mfQueueRestartEnabled ? 'enabled' : 'disabled'}.`);
        });

        function saveQueueRestartThresholdInput(showStatus) {
            const value = parseInt(queueRestartThresholdInput.value, 10);

            if (!Number.isFinite(value)) return;

            mfQueueRestartThreshold = Math.max(
                1,
                Math.min(999, value)
            );

            queueRestartThresholdInput.value =
                mfQueueRestartThreshold;

            localStorage.setItem(
                'mf_next_queue_restart_threshold_v10_1_3',
                String(mfQueueRestartThreshold)
            );

            if (showStatus) {
                updateStatusBox(
                    `Queue restart threshold set to ${mfQueueRestartThreshold}.`
                );
            }
        }

        queueRestartThresholdInput.addEventListener(
            'input',
            function() {
                saveQueueRestartThresholdInput(false);
            }
        );

        queueRestartThresholdInput.addEventListener(
            'change',
            function() {
                saveQueueRestartThresholdInput(true);
            }
        );


        const unitFinderBtn = document.createElement('button');
        unitFinderBtn.textContent = 'Unit Finder';
        unitFinderBtn.className = 'mf2026-button';
        unitFinderBtn.style.backgroundColor = 'orange';
        unitFinderBtn.style.color = 'black';
        unitFinderBtn.addEventListener('click', async function() {
            updateStatusBox('Unit Finder clicked');
            await handleCombinedLogic();
        });

        const allyStealBtn = document.createElement('button');
        allyStealBtn.id = 'mf-ally-steal';
        allyStealBtn.textContent = 'Ally Steal';
        allyStealBtn.className = 'mf2026-button';
        allyStealBtn.style.backgroundColor = '#ff69b4';
        allyStealBtn.style.color = 'black';
        allyStealBtn.addEventListener('click', async function() {
            if (allyStealBtn.disabled) return;

            allyStealBtn.disabled = true;
            allyStealBtn.textContent = 'Sending...';

            try {
                await handleAllySteal();
            } finally {
                allyStealBtn.disabled = false;
                allyStealBtn.textContent = 'Ally Steal';
            }
        });

        const missionUpdateBtn = document.createElement('button');
        missionUpdateBtn.id = 'mission-update-box';
        missionUpdateBtn.textContent = 'Mission Update';
        missionUpdateBtn.className = 'mf2026-button';
        missionUpdateBtn.style.backgroundColor = '#0d6efd';
        missionUpdateBtn.style.color = 'white';
        missionUpdateBtn.addEventListener(
            'click',
            async function() {
                if (
                    missionUpdateBtn.disabled
                ) {
                    return;
                }

                missionUpdateBtn.disabled =
                    true;

                const originalText =
                    missionUpdateBtn.textContent;

                missionUpdateBtn.textContent =
                    'Loading...';

                try {
                    updateStatusBox(
                        'Mission Update: loading the full available vehicle list...'
                    );

                    const manualVehicleLoadState =
                        await ensureVehicleListLoaded({
                            requireNonZero: true
                        });

                    if (!manualVehicleLoadState.ready) {
                        vehicleLoadState.ready = false;
                        changeDispatchBoxColor(false);
                        updateStatusBox(
                            'Mission Update stopped: the complete vehicle list did not become stable.'
                        );
                        return;
                    }

                    // A mission refresh can leave the previous UPDATE
                    // selection key in memory. Start this manual update as
                    // a fresh pass so Fire Engine and other repeated update
                    // requirements are actually searched again.
                    clearSelectionGuards();

                    const manualUpdateRows =
                        readMissionUpdateRows();

                    await preparePoliceVehicleSafetyForRows(
                        manualUpdateRows,
                        'MANUAL UPDATE'
                    );

                    handleMissionUpdateUnits(
                        true,
                        manualUpdateRows
                    );
                } finally {
                    missionUpdateBtn.disabled =
                        false;

                    missionUpdateBtn.textContent =
                        originalText;
                }
            }
        );

        const dispatchBtn = document.createElement('button');
        dispatchBtn.id = 'dispatch-box';
        dispatchBtn.textContent = 'Dispatch';
        dispatchBtn.className = 'mf2026-button';
        dispatchBtn.style.backgroundColor = 'grey';
        dispatchBtn.style.color = 'white';
        dispatchBtn.addEventListener('click', function() {
            triggerDispatchClick();
        });

        const dispatchShareBtn = document.createElement('button');
        dispatchShareBtn.id = 'dispatch-share-box';
        dispatchShareBtn.textContent = 'Dispatch & Share';
        dispatchShareBtn.className = 'mf2026-button';
        dispatchShareBtn.style.backgroundColor = '#198754';
        dispatchShareBtn.style.color = 'white';
        dispatchShareBtn.addEventListener('click', function() {
            triggerDispatchShareClick();
        });

        const autoModeBtn = document.createElement('button');
        autoModeBtn.id = 'auto-mode-box';
        autoModeBtn.textContent = 'Auto Mode: Start';
        autoModeBtn.className = 'mf2026-button';
        autoModeBtn.style.backgroundColor = '#6f42c1';
        autoModeBtn.style.color = 'white';
        autoModeBtn.addEventListener('click', function() {
            toggleAutoMode();
        });

        const finderButtonRow = document.createElement('div');
        finderButtonRow.className = 'mf2026-button-row';
        finderButtonRow.appendChild(unitFinderBtn);
        finderButtonRow.appendChild(allyStealBtn);
        controlBody.appendChild(finderButtonRow);

        const missionDispatchRow = document.createElement('div');
        missionDispatchRow.className = 'mf2026-button-row';
        missionDispatchRow.appendChild(missionUpdateBtn);
        missionDispatchRow.appendChild(dispatchBtn);
        controlBody.appendChild(missionDispatchRow);

        controlBody.appendChild(dispatchShareBtn);
        controlBody.appendChild(autoModeBtn);


        panel.appendChild(controlBody);

        function syncMissionControlCollapseButton() {
            const expanded = !mfMissionControlCollapsed;
            controlMinimizeBtn.textContent = missionFinderIosSafari
                ? (expanded ? '▴' : '▾')
                : (expanded ? '−' : '+');
            controlMinimizeBtn.title = expanded
                ? 'Collapse Mission Control'
                : 'Expand Mission Control';
            controlMinimizeBtn.setAttribute(
                'aria-label',
                controlMinimizeBtn.title
            );
            controlMinimizeBtn.setAttribute(
                'aria-expanded',
                String(expanded)
            );
        }

        function toggleMissionControlCollapsed() {
            mfMissionControlCollapsed = !mfMissionControlCollapsed;
            localStorage.setItem(
                MF_CONTROL_COLLAPSED_KEY,
                String(mfMissionControlCollapsed)
            );
            panel.classList.toggle(
                'mf2026-control-collapsed',
                mfMissionControlCollapsed
            );
            syncMissionControlCollapseButton();

            if (!mfMissionControlCollapsed) {
                renderVehicleLoadList();
            }

            requestAnimationFrame(() => {
                keepMissionFinderWindowOnScreen(wrapper);
            });
        }

        syncMissionControlCollapseButton();

        controlMinimizeBtn.addEventListener(
            'click',
            toggleMissionControlCollapsed
        );
        dragHandle.addEventListener('click', function() {
            if (mfMissionControlCollapsed) {
                toggleMissionControlCollapsed();
            }
        });

        const loadPanel = document.createElement('div');
        loadPanel.id = 'vehicle-load-list-box';
        loadPanel.className = `mf2026-panel ${mfVehicleLoadCollapsed ? 'mf2026-load-collapsed' : ''}`;

        loadPanel.innerHTML = `
            <div class="mf2026-load-header-row">
                <div id="mf-load-title" class="mf2026-header">Vehicle Load List</div>
                <button id="mf-load-minimize" class="mf2026-button" title="Minimize / expand vehicle load list">${mfVehicleLoadCollapsed ? '+' : '−'}</button>
            </div>

            <div class="mf-load-body">
                <div class="mf2026-box">
                    <div class="mf2026-section-title">Progress</div>
                    <div id="vehicle-load-summary" class="mf2026-small">No mission loaded</div>
                    <div class="mf2026-progress-wrap" style="margin-top:6px;">
                        <div id="vehicle-load-progress" class="mf2026-progress-bar"></div>
                    </div>
                </div>

                <div class="mf2026-box">
                    <div class="mf2026-section-title">Required Vehicles <span class="mf2026-small">(selected / required)</span></div>
                    <div id="vehicle-load-list-content" class="mf2026-small">
                        Click Unit Finder to load vehicles.
                    </div>
                </div>

                <div class="mf2026-box">
                    <div class="mf2026-section-title">Patients</div>
                    <div id="vehicle-patient-content" class="mf2026-small">
                        No patients checked yet.
                    </div>
                </div>

                <div class="mf2026-box">
                    <div class="mf2026-section-title">Session</div>
                    <div id="session-panel-content" class="mf2026-small">
                        No session data yet.
                    </div>
                </div>
            </div>
        `;

        wrapper.appendChild(panel);
        wrapper.appendChild(loadPanel);
        document.body.appendChild(wrapper);

        function toggleVehicleLoadCollapsed() {
            mfVehicleLoadCollapsed = !mfVehicleLoadCollapsed;
            localStorage.setItem(
                MF_VEHICLE_LOAD_COLLAPSED_KEY,
                String(mfVehicleLoadCollapsed)
            );
            loadPanel.classList.toggle('mf2026-load-collapsed', mfVehicleLoadCollapsed);

            const minimizeButton = loadPanel.querySelector('#mf-load-minimize');
            if (minimizeButton) {
                minimizeButton.textContent = mfVehicleLoadCollapsed ? '+' : '−';
            }

            renderVehicleLoadList();
            renderSessionPanel();
        }

        const loadMinimizeButton = loadPanel.querySelector('#mf-load-minimize');
        const loadTitle = loadPanel.querySelector('#mf-load-title');

        if (loadMinimizeButton) {
            loadMinimizeButton.addEventListener('click', toggleVehicleLoadCollapsed);
        }

        if (loadTitle) {
            loadTitle.addEventListener('click', function() {
                if (mfVehicleLoadCollapsed) toggleVehicleLoadCollapsed();
            });
        }

        keepPanelPositionCheckbox.addEventListener(
            'change',
            function() {
                mfKeepPanelPosition = this.checked;

                localStorage.setItem(
                    MF_KEEP_PANEL_POSITION_KEY,
                    String(mfKeepPanelPosition)
                );

                if (mfKeepPanelPosition) {
                    saveMissionFinderWindowPosition(
                        wrapper,
                        'position checkbox enabled'
                    );

                    updateStatusBox(
                        'Saved panel position enabled. Drag it to set the default position.'
                    );
                } else {
                    localStorage.removeItem(MF_PANEL_LEFT_KEY);
                    localStorage.removeItem(MF_PANEL_TOP_KEY);

                    centreMissionFinderWindow(
                        wrapper,
                        'position checkbox disabled'
                    );

                    updateStatusBox(
                        'Saved panel position disabled. The panel will open centred.'
                    );
                }
            }
        );

        controlCentreBtn.addEventListener('click', function(event) {
            event.preventDefault();
            event.stopPropagation();

            centreMissionFinderWindow(
                wrapper,
                'centre button'
            );

            updateStatusBox(
                mfKeepPanelPosition
                    ? 'Mission Control centred and saved as the new preset position.'
                    : 'Mission Control moved back to the centre.'
            );
        });

        makePanelDraggable(wrapper, dragHandle);

        if (missionFinderIosSafari) {
            resetMissionFinderIosPosition(
                wrapper,
                'control window opened'
            );
        } else if (
            !applySavedMissionFinderWindowPosition(
                wrapper,
                'control window opened'
            )
        ) {
            centreMissionFinderWindow(
                wrapper,
                'control window opened'
            );
        }

        renderVehicleLoadList();
        renderSessionPanel();
        startSessionRuntimeTicker();
        updateAutoModeButton();
        renderDebugPanel();
        renderRecorderStatus();

        installMissionFinderResizeHandler();

        if (autoModeRunning && !autoModeLoopActive && !isManualAutoStopActive()) {
            updateStatusBox('Auto Mode restored after mission load.');
            scheduleAutoModeLoopResume(
                'control panel created'
            );
        }
    }

    function installMissionFinderResizeHandler() {
        if (mfMissionFinderResizeHandler) return;

        mfMissionFinderResizeHandler = function(event) {
            const activeWrapper =
                document.getElementById(
                    'mission-finder-wrapper'
                );

            if (!activeWrapper) return;

            if (
                isMissionFinderIosSafariWebsite()
                && (
                    event?.type === 'orientationchange'
                    || event?.type === 'pageshow'
                )
            ) {
                resetMissionFinderIosPosition(
                    activeWrapper,
                    event.type
                );
                return;
            }

            keepMissionFinderWindowOnScreen(
                activeWrapper
            );

            if (
                !isMissionFinderIosSafariWebsite()
                && mfKeepPanelPosition
            ) {
                saveMissionFinderWindowPosition(
                    activeWrapper,
                    'browser resized'
                );
            }
        };

        window.addEventListener(
            'resize',
            mfMissionFinderResizeHandler,
            { passive: true }
        );

        if (isMissionFinderIosSafariWebsite()) {
            window.addEventListener(
                'orientationchange',
                mfMissionFinderResizeHandler,
                { passive: true }
            );
            window.addEventListener(
                'pageshow',
                mfMissionFinderResizeHandler,
                { passive: true }
            );
            window.visualViewport?.addEventListener(
                'resize',
                mfMissionFinderResizeHandler,
                { passive: true }
            );
            window.visualViewport?.addEventListener(
                'scroll',
                mfMissionFinderResizeHandler,
                { passive: true }
            );
        }
    }

    function saveMissionFinderWindowPosition(panel, reason) {
        if (
            !panel
            || !mfKeepPanelPosition
            || isMissionFinderIosSafariWebsite()
        ) return;

        keepMissionFinderWindowOnScreen(panel);

        const left = panel.style.left ||
            `${Math.round(panel.getBoundingClientRect().left)}px`;

        const top = panel.style.top ||
            `${Math.round(panel.getBoundingClientRect().top)}px`;

        localStorage.setItem(MF_PANEL_LEFT_KEY, left);
        localStorage.setItem(MF_PANEL_TOP_KEY, top);

        if (mfDebugEnabled) {
            debugLog(
                'CONTROL WINDOW',
                `Saved position | reason=${reason || 'unknown'} | left=${left} | top=${top}`
            );
        }
    }

    function applySavedMissionFinderWindowPosition(panel, reason) {
        if (
            !panel
            || isMissionFinderIosSafariWebsite()
        ) return false;

        const left = localStorage.getItem(MF_PANEL_LEFT_KEY);
        const top = localStorage.getItem(MF_PANEL_TOP_KEY);

        if (!mfKeepPanelPosition || !left || !top) {
            return false;
        }

        panel.style.left = left;
        panel.style.top = top;
        panel.style.right = 'auto';
        panel.style.bottom = 'auto';
        panel.style.visibility = 'visible';

        requestAnimationFrame(() => {
            keepMissionFinderWindowOnScreen(panel);
            saveMissionFinderWindowPosition(
                panel,
                reason || 'apply saved position'
            );
        });

        if (mfDebugEnabled) {
            debugLog(
                'CONTROL WINDOW',
                `Applied saved position | reason=${reason || 'unknown'} | left=${left} | top=${top}`
            );
        }

        return true;
    }


    function getMissionFinderViewportBounds() {
        const viewport = window.visualViewport;
        const left = Math.max(
            0,
            Number(viewport?.offsetLeft || 0)
        );
        const top = Math.max(
            0,
            Number(viewport?.offsetTop || 0)
        );
        const width = Math.max(
            1,
            Number(
                viewport?.width
                || window.innerWidth
                || 1
            )
        );
        const height = Math.max(
            1,
            Number(
                viewport?.height
                || window.innerHeight
                || 1
            )
        );

        return {
            left,
            top,
            width,
            height,
            right: left + width,
            bottom: top + height
        };
    }

    function resetMissionFinderIosPosition(panel, reason) {
        if (
            !panel
            || !isMissionFinderIosSafariWebsite()
        ) {
            return false;
        }

        panel.style.left = '';
        panel.style.top = '';
        panel.style.right = '';
        panel.style.bottom = '';
        panel.style.width = '';
        panel.style.visibility = 'visible';

        localStorage.removeItem(MF_PANEL_LEFT_KEY);
        localStorage.removeItem(MF_PANEL_TOP_KEY);

        requestAnimationFrame(() => {
            keepMissionFinderWindowOnScreen(panel);
        });

        if (mfDebugEnabled) {
            debugLog(
                'CONTROL WINDOW',
                `iOS Safari top placement restored | reason=${reason || 'unknown'}`
            );
        }

        return true;
    }

    function centreMissionFinderWindow(panel, reason) {
        if (!panel) return;

        if (
            resetMissionFinderIosPosition(
                panel,
                reason || 'centre requested'
            )
        ) {
            return;
        }

        const applyCentre = () => {
            const rect = panel.getBoundingClientRect();
            const margin = 8;

            const availableWidth = Math.max(
                0,
                window.innerWidth - rect.width
            );

            const availableHeight = Math.max(
                0,
                window.innerHeight - rect.height
            );

            const left = Math.max(
                margin,
                Math.round(availableWidth / 2)
            );

            const top = Math.max(
                margin,
                Math.round(availableHeight / 2)
            );

            panel.style.left = `${left}px`;
            panel.style.top = `${top}px`;
            panel.style.right = 'auto';
            panel.style.bottom = 'auto';
            panel.style.visibility = 'visible';

            localStorage.removeItem('panel-left');
            localStorage.removeItem('panel-top');

            if (mfKeepPanelPosition) {
                localStorage.setItem(
                    MF_PANEL_LEFT_KEY,
                    panel.style.left
                );
                localStorage.setItem(
                    MF_PANEL_TOP_KEY,
                    panel.style.top
                );
            } else {
                localStorage.removeItem(MF_PANEL_LEFT_KEY);
                localStorage.removeItem(MF_PANEL_TOP_KEY);
            }

            if (mfDebugEnabled) {
                debugLog(
                    'CONTROL WINDOW',
                    `Centred | reason=${reason || 'unknown'} | left=${left}px | top=${top}px`
                );
            }
        };

        requestAnimationFrame(() => {
            requestAnimationFrame(applyCentre);
        });
    }

    function keepMissionFinderWindowOnScreen(panel) {
        if (!panel) return;

        if (
            isMissionFinderIosSafariWebsite()
            && !panel.style.left
            && !panel.style.top
        ) {
            panel.style.visibility = 'visible';
            return;
        }

        const rect = panel.getBoundingClientRect();
        const margin = 8;
        const missionFinderIosSafari =
            isMissionFinderIosSafariWebsite();
        const bounds = missionFinderIosSafari
            ? getMissionFinderViewportBounds()
            : {
                left: 0,
                top: 0,
                right: window.innerWidth,
                bottom: window.innerHeight,
                width: window.innerWidth,
                height: window.innerHeight
            };

        const maxLeft = Math.max(
            bounds.left + margin,
            bounds.right - rect.width - margin
        );

        const maxTop = missionFinderIosSafari
            ? Math.max(
                bounds.top + margin,
                bounds.bottom - 48
            )
            : Math.max(
                margin,
                window.innerHeight - Math.min(
                    rect.height,
                    window.innerHeight - margin
                )
            );

        const currentLeft = parseFloat(panel.style.left);
        const currentTop = parseFloat(panel.style.top);

        const safeLeft = Math.min(
            maxLeft,
            Math.max(
                bounds.left + margin,
                Number.isFinite(currentLeft)
                    ? currentLeft
                    : rect.left
            )
        );

        const safeTop = Math.min(
            maxTop,
            Math.max(
                bounds.top + margin,
                Number.isFinite(currentTop)
                    ? currentTop
                    : rect.top
            )
        );

        panel.style.left = `${Math.round(safeLeft)}px`;
        panel.style.top = `${Math.round(safeTop)}px`;
        panel.style.right = 'auto';
        panel.style.visibility = 'visible';
    }

    function makePanelDraggable(panel, dragHandle) {
        if (
            isMissionFinderIosSafariWebsite()
            && window.PointerEvent
        ) {
            let activePointerId = null;
            let startX = 0;
            let startY = 0;
            let startLeft = 0;
            let startTop = 0;
            let moved = false;

            const finishPointerDrag = event => {
                if (
                    activePointerId == null
                    || (
                        event?.pointerId != null
                        && event.pointerId !== activePointerId
                    )
                ) {
                    return;
                }

                if (
                    dragHandle.hasPointerCapture?.(
                        activePointerId
                    )
                ) {
                    try {
                        dragHandle.releasePointerCapture(
                            activePointerId
                        );
                    } catch (_error) {}
                }

                activePointerId = null;
                keepMissionFinderWindowOnScreen(panel);

                localStorage.removeItem(MF_PANEL_LEFT_KEY);
                localStorage.removeItem(MF_PANEL_TOP_KEY);
                localStorage.removeItem('panel-left');
                localStorage.removeItem('panel-top');

                if (moved) {
                    const suppressClick = clickEvent => {
                        clickEvent.preventDefault();
                        clickEvent.stopPropagation();
                    };
                    dragHandle.addEventListener(
                        'click',
                        suppressClick,
                        {
                            once: true,
                            capture: true
                        }
                    );
                }
            };

            dragHandle.addEventListener(
                'pointerdown',
                event => {
                    if (
                        event.button != null
                        && event.button !== 0
                    ) {
                        return;
                    }

                    const rect =
                        panel.getBoundingClientRect();

                    activePointerId = event.pointerId;
                    startX = event.clientX;
                    startY = event.clientY;
                    startLeft = rect.left;
                    startTop = rect.top;
                    moved = false;

                    panel.style.width =
                        `${Math.round(rect.width)}px`;
                    panel.style.left =
                        `${Math.round(startLeft)}px`;
                    panel.style.top =
                        `${Math.round(startTop)}px`;
                    panel.style.right = 'auto';
                    panel.style.bottom = 'auto';

                    try {
                        dragHandle.setPointerCapture?.(
                            activePointerId
                        );
                    } catch (_error) {}

                    event.preventDefault();
                }
            );

            dragHandle.addEventListener(
                'pointermove',
                event => {
                    if (
                        activePointerId == null
                        || event.pointerId !== activePointerId
                    ) {
                        return;
                    }

                    const deltaX =
                        event.clientX - startX;
                    const deltaY =
                        event.clientY - startY;

                    if (
                        Math.abs(deltaX) > 4
                        || Math.abs(deltaY) > 4
                    ) {
                        moved = true;
                    }

                    const bounds =
                        getMissionFinderViewportBounds();
                    const rect =
                        panel.getBoundingClientRect();
                    const margin = 8;

                    const maxLeft = Math.max(
                        bounds.left + margin,
                        bounds.right - rect.width - margin
                    );
                    const maxTop = Math.max(
                        bounds.top + margin,
                        bounds.bottom - 48
                    );

                    const nextLeft = Math.min(
                        maxLeft,
                        Math.max(
                            bounds.left + margin,
                            startLeft + deltaX
                        )
                    );
                    const nextTop = Math.min(
                        maxTop,
                        Math.max(
                            bounds.top + margin,
                            startTop + deltaY
                        )
                    );

                    panel.style.left =
                        `${Math.round(nextLeft)}px`;
                    panel.style.top =
                        `${Math.round(nextTop)}px`;

                    event.preventDefault();
                }
            );

            dragHandle.addEventListener(
                'pointerup',
                finishPointerDrag
            );
            dragHandle.addEventListener(
                'pointercancel',
                finishPointerDrag
            );

            return;
        }

        let isDragging = false;
        let startX, startY, initialLeft, initialTop;

        dragHandle.addEventListener('mousedown', function(e) {
            if (e.button !== 0) return;

            isDragging = true;
            startX = e.clientX;
            startY = e.clientY;

            const computed = window.getComputedStyle(panel);

            initialLeft = parseInt(computed.left, 10);
            initialTop = parseInt(computed.top, 10);

            if (!Number.isFinite(initialLeft)) {
                initialLeft = panel.getBoundingClientRect().left;
            }

            if (!Number.isFinite(initialTop)) {
                initialTop = panel.getBoundingClientRect().top;
            }

            e.preventDefault();

            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp);
        });

        function onMouseMove(e) {
            if (!isDragging) return;

            const rect = panel.getBoundingClientRect();
            const margin = 8;

            const requestedLeft =
                initialLeft + e.clientX - startX;

            const requestedTop =
                initialTop + e.clientY - startY;

            const maxLeft = Math.max(
                margin,
                window.innerWidth - rect.width - margin
            );

            const visibleHeaderHeight = 48;

            const maxTop = Math.max(
                margin,
                window.innerHeight - visibleHeaderHeight
            );

            panel.style.left = `${
                Math.round(
                    Math.min(
                        maxLeft,
                        Math.max(margin, requestedLeft)
                    )
                )
            }px`;

            panel.style.top = `${
                Math.round(
                    Math.min(
                        maxTop,
                        Math.max(margin, requestedTop)
                    )
                )
            }px`;
        }

        function onMouseUp() {
            if (!isDragging) return;

            isDragging = false;

            document.removeEventListener('mousemove', onMouseMove);
            document.removeEventListener('mouseup', onMouseUp);

            keepMissionFinderWindowOnScreen(panel);

            if (mfKeepPanelPosition) {
                saveMissionFinderWindowPosition(
                    panel,
                    'drag completed'
                );
            } else {
                localStorage.removeItem(MF_PANEL_LEFT_KEY);
                localStorage.removeItem(MF_PANEL_TOP_KEY);
            }

            localStorage.removeItem('panel-left');
            localStorage.removeItem('panel-top');
        }
    }

    function getMissionReadyDelay() {
        const value = parseInt(localStorage.getItem('mf_mission_ready_delay_ms') || String(missionReadyDelayMs), 10);
        return Number.isFinite(value) ? Math.max(500, Math.min(15000, value)) : DEFAULT_MISSION_READY_DELAY;
    }

    function getDispatchReadinessSignature() {
        const selectedCount = document.querySelectorAll(
            'input[type="checkbox"]:checked, input.vehicle_checkbox:checked'
        ).length;

        const now = Date.now();

        if (now >= mfDispatchReadinessExpensiveCache.expiresAt) {
            mfDispatchReadinessExpensiveCache = {
                expiresAt: now + 200,
                updateRowsSignature: getMissionUpdateRowsSignature(
                    readMissionUpdateRows({
                        silent: true
                    })
                ),
                staffingText: getVisibleStaffingShortageText()
            };
        }

        const rowState = vehicleLoadState.rows
            .map(row => [
                row.originalName,
                row.mappedName,
                row.required,
                row.found,
                row.status
            ].join(':'))
            .sort()
            .join('|');

        return [
            selectedCount,
            mfDispatchReadinessExpensiveCache.updateRowsSignature,
            rowState,
            vehicleLoadState.ready ? 'ready' : 'not-ready',
            isLoadingBarVisible() ? 'loading' : 'idle',
            mfDispatchReadinessExpensiveCache.staffingText
        ].join('||');
    }

    async function waitForFastDispatchReadiness(
        reason,
        options = {}
    ) {
        const minimumWait = Number.isFinite(options.minimumWait)
            ? options.minimumWait
            : 250;

        const stableFor = Number.isFinite(options.stableFor)
            ? options.stableFor
            : 450;

        const timeout = Number.isFinite(options.timeout)
            ? options.timeout
            : 2000;

        const startedAt = Date.now();
        let lastSignature = '';
        let stableSince = 0;

        while (Date.now() - startedAt < timeout) {
            if (
                isManualAutoStopActive() ||
                !autoModeRunning
            ) {
                return false;
            }

            if (
                detectAndLatchStaffingBlock(
                    `fast-ready-${reason}`
                )
            ) {
                return false;
            }

            const signature =
                getDispatchReadinessSignature();

            if (signature !== lastSignature) {
                lastSignature = signature;
                stableSince = Date.now();
            }

            const elapsed = Date.now() - startedAt;
            const stableElapsed = Date.now() - stableSince;

            if (
                elapsed >= minimumWait &&
                stableElapsed >= stableFor &&
                !isLoadingBarVisible()
            ) {
                if (mfDebugEnabled) {
                    debugLog(
                        'FAST DISPATCH',
                        `${reason || 'selection'} stable after ${elapsed}ms`
                    );
                }

                return true;
            }

            await wait(100);
        }

        if (mfDebugEnabled) {
            debugLog(
                'FAST DISPATCH',
                `${reason || 'selection'} reached ${timeout}ms safety limit`
            );
        }

        return true;
    }


    function createDefaultSessionStats() {
        return {
            startedAt: Date.now(),
            completed: 0,
            skipped: 0,
            updates: 0,
            credits: 0,
            entries: []
        };
    }

    function loadSessionStats() {
        try {
            const raw = sessionStorage.getItem(SESSION_STATS_KEY);
            if (!raw) return createDefaultSessionStats();

            const parsed = JSON.parse(raw);
            return Object.assign(createDefaultSessionStats(), parsed, {
                entries: Array.isArray(parsed.entries) ? parsed.entries : []
            });
        } catch (error) {
            console.warn('Mission Control session stats reset after parse error:', error);
            return createDefaultSessionStats();
        }
    }

    function saveSessionStats(stats) {
        sessionStorage.setItem(SESSION_STATS_KEY, JSON.stringify(stats));
    }

    function getCurrentMissionName() {
        const generalInfo = document.querySelector('#mission_general_info');

        if (generalInfo) {
            const dataTitle = generalInfo.getAttribute('data-mission-title');

            if (dataTitle && dataTitle.trim()) {
                return dataTitle.trim();
            }
        }

        const missionH1 = document.querySelector('#missionH1');

        if (missionH1) {
            const title = missionH1.innerText.replace(/\s+/g,' ').trim();
            if (title) return title;
        }

        const candidates=[
            '#mission_caption',
            '#mission_general_info h1',
            '.mission_title',
            '.mission-title',
            'h1',
            'h2'
        ];

        for(const selector of candidates){
            const element=document.querySelector(selector);
            const text=element&&element.innerText?element.innerText.replace(/\s+/g,' ').trim():'';
            if(text && !text.toLowerCase().includes('mission control')){
                return text;
            }
        }

        return 'Mission';
    }

    function getCurrentMissionValueScope() {
        const missionInfo =
            document.querySelector('#mission_general_info');

        const missionModal =
            missionInfo &&
            missionInfo.closest &&
            missionInfo.closest('.vm--modal, .modal, .lightbox');

        return missionModal ||
            document.querySelector(
                '#mission_general_info, #mission_content, #iframe-inside-container'
            ) ||
            document;
    }

    function parseCreditValueFromText(text) {
        const value = String(text || '')
            .replace(/\u00a0/g, ' ')
            .replace(/\s+/g, ' ')
            .trim();

        if (!value) return 0;

        const patterns = [
            /(?:average\s+credits?|mission\s+value|reward|credits?)\s*:?\s*~?\s*([\d,.]+)/i,
            /~?\s*([\d,.]+)\s*credits?/i
        ];

        for (const pattern of patterns) {
            const match = value.match(pattern);

            if (!match) continue;

            const parsed = parseInt(
                match[1].replace(/[^\d]/g, ''),
                10
            );

            if (
                Number.isFinite(parsed) &&
                parsed > 0 &&
                parsed < 100000000
            ) {
                return parsed;
            }
        }

        return 0;
    }

    function getMissionCredits() {
        const scope = getCurrentMissionValueScope();

        const attributeCandidates = Array.from(
            scope.querySelectorAll(
                '[data-mission-credits], [data-credits], [data-reward]'
            )
        );

        for (const element of attributeCandidates) {
            const raw =
                element.getAttribute('data-mission-credits') ||
                element.getAttribute('data-credits') ||
                element.getAttribute('data-reward') ||
                '';

            const parsed = parseInt(
                String(raw).replace(/[^\d]/g, ''),
                10
            );

            if (Number.isFinite(parsed) && parsed > 0) {
                return parsed;
            }
        }

        const badgeCandidates = Array.from(
            scope.querySelectorAll(
                'span.badge, .badge, .label, #mission_help, #mission_general_info'
            )
        );

        for (const element of badgeCandidates) {
            const parsed = parseCreditValueFromText(
                element.innerText ||
                element.textContent ||
                ''
            );

            if (parsed > 0) return parsed;
        }

        const scopeText = (
            scope.innerText ||
            scope.textContent ||
            ''
        ).replace(/\s+/g, ' ').trim();

        return parseCreditValueFromText(scopeText);
    }

    function formatRuntime(ms) {
        const totalSeconds = Math.max(0, Math.floor(ms / 1000));
        const hours = Math.floor(totalSeconds / 3600);
        const minutes = Math.floor((totalSeconds % 3600) / 60);
        const seconds = totalSeconds % 60;

        return [hours, minutes, seconds]
            .map(value => String(value).padStart(2, '0'))
            .join(':');
    }

    function formatMoney(value) {
        const number = Number(value || 0);
        return `£${number.toLocaleString('en-GB')}`;
    }

    function addMissionLogEntry(type, missionName, detail, credits) {
        const stats = loadSessionStats();
        const safeCredits = Number.isFinite(Number(credits)) ? Number(credits) : 0;

        if (type === 'completed') {
            stats.completed += 1;
            stats.credits += safeCredits;
        }

        if (type === 'skipped') {
            stats.skipped += 1;
        }

        if (type === 'update') {
            stats.updates += 1;
        }

        stats.entries.unshift({
            type,
            missionName: missionName || 'Mission',
            detail: detail || '',
            credits: safeCredits,
            hasCredits: Number.isFinite(Number(credits)) && Number(credits) > 0,
            timestamp: Date.now()
        });

        stats.entries = stats.entries.slice(0, 25);
        saveSessionStats(stats);
        renderSessionPanel();
    }

    function renderSessionPanel() {
        const container = document.getElementById('session-panel-content');
        if (!container) return;

        const stats = loadSessionStats();
        const runtimeMs = Date.now() - Number(stats.startedAt || Date.now());
        const completed = Number(stats.completed || 0);
        const skipped = Number(stats.skipped || 0);
        const updates = Number(stats.updates || 0);
        const credits = Number(stats.credits || 0);
        const hours = Math.max(runtimeMs / 3600000, 0.001);
        const average = completed > 0 ? Math.round(credits / completed) : 0;
        const creditsPerHour = Math.round(credits / hours);
        const missionsPerHour = Math.round(completed / hours);

        const successRate = (completed + skipped) > 0
            ? (((completed / (completed + skipped)) * 100).toFixed(1) + '%')
            : '----';

        container.innerHTML = `
            <div class="mf2026-stat-grid">
                <span>Runtime</span><strong>${formatRuntime(runtimeMs)}</strong>
                <span>Completed</span><strong>${completed}</strong>
                <span>Skipped</span><strong>${skipped}</strong>
                <span>Updates</span><strong>${updates}</strong>
                <span>Credits</span><strong>${formatMoney(credits)}</strong>
                <span>Average</span><strong>${completed > 0 ? formatMoney(average) : '----'}</strong>
                <span>Credits/hr</span><strong>${completed > 0 ? formatMoney(creditsPerHour) : '----'}</strong>
                <span>Missions/hr</span><strong>${completed > 0 ? missionsPerHour : '----'}</strong>
                <span>Success</span><strong>${successRate}</strong>
            </div>
        `;
    }

let sessionRuntimeTicker = null;

    function stopSessionRuntimeTicker() {
        if (!sessionRuntimeTicker) return;
        clearInterval(sessionRuntimeTicker);
        sessionRuntimeTicker = null;
    }

    function startSessionRuntimeTicker() {
        if (sessionRuntimeTicker) return;

        sessionRuntimeTicker = setInterval(() => {
            if (!document.getElementById('session-panel-content')) {
                stopSessionRuntimeTicker();
                return;
            }

            renderSessionPanel();
        }, 2000);
    }

    async function waitForMissionReady() {
        const timeoutMs = Math.max(4500, getMissionReadyDelay() + 2500);
        const started = Date.now();
        let stableSince = 0;
        let lastDeepProbeAt = 0;
        let hasPatientData = false;
        let hasUpdateRows = false;

        while (Date.now() - started < timeoutMs) {
            const hasMission = isMissionPage();
            const hasUnits = !!document.querySelector('a[search_attribute]');
            const hasMissionHelp = !!document.querySelector('#mission_help');
            const hasBasicMissionUi = hasMission && hasUnits && hasMissionHelp;

            if (hasBasicMissionUi) {
                if (!stableSince) stableSince = Date.now();

                const now = Date.now();

                if (now - lastDeepProbeAt >= 300) {
                    lastDeepProbeAt = now;
                    hasPatientData = findPatientCount(true) > 0;
                    hasUpdateRows = readMissionUpdateRows({
                        silent: true
                    }).length > 0;
                }

                // Give dynamic patient cards at least 1.5 seconds after the
                // basic mission controls appear. They often render later.
                if (
                    hasPatientData ||
                    hasUpdateRows ||
                    Date.now() - stableSince >= 650
                ) {
                    break;
                }
            } else {
                stableSince = 0;
                hasPatientData = false;
                hasUpdateRows = false;
            }

            await wait(150);
        }

        const configuredDelay = getMissionReadyDelay();
        const finalReadyDelay =
            hasPatientData || hasUpdateRows
                ? Math.min(configuredDelay, 350)
                : configuredDelay;

        await wait(finalReadyDelay);
        requireMissionUpdateFirstPass('mission ready / content refreshed');
    }

    function updateStatusBox(message) {
        const statusBox = document.getElementById('status-box');
        if (statusBox) statusBox.textContent = message;

        if (mfDebugEnabled) {
            debugLog('STATUS', message);
        }
    }

    function updateAutoModeButton() {
        const button = document.getElementById('auto-mode-box');

        if (!button) return;

        if (autoModeRunning) {
            button.textContent = 'Auto Mode: Stop';
            button.style.backgroundColor = '#dc3545';
        } else {
            button.textContent = 'Auto Mode: Start';
            button.style.backgroundColor = '#6f42c1';
        }
    }

    function changeDispatchBoxColor(isComplete) {
        const problemAlert = getVisibleInlineProblemAlertText();

        if (isComplete && problemAlert) {
            isComplete = false;

            if (mfDebugEnabled) {
                debugLog('READY BLOCK', `Problem alert still visible, blocking ready: ${problemAlert.slice(0, 260)}`);
            }

            try {
                recordIssueEvent('READY BLOCKED BY PROBLEM ALERT', {
                    problemAlert
                }, true);
            } catch (error) {}
        }

        const dispatchBox = document.getElementById('dispatch-box');

        if (dispatchBox) {
            dispatchBox.style.backgroundColor = isComplete ? 'green' : 'grey';

            if (isComplete) {
                updateStatusBox('Units ready for dispatch.');
            }
        }

        vehicleLoadState.ready = !!isComplete;
        renderVehicleLoadList();
    }

    function resetVehicleLoadState() {
        clearSelectionGuards();
        invalidateVehicleCheckboxCache();
        vehicleLoadState = {
            rows: [],
            patients: 0,
            ambulances: 0,
            ambulanceOfficer: false,
            ready: false
        };
    }

    function addOrUpdateVehicleRow(originalName, mappedName, required, status, selected) {
        const safeRequired = Math.max(0, parseInt(required, 10) || 0);
        const safeSelected = Number.isFinite(Number(selected)) ? Math.max(0, Math.min(Number(selected), safeRequired)) : countSelectedMatchingVehicles(originalName, mappedName);
        const existing = vehicleLoadState.rows.find(row => row.originalName === originalName && row.mappedName === mappedName);

        if (existing) {
            existing.mappedName = mappedName;
            existing.required = safeRequired;
            existing.selected = Math.min(safeSelected, safeRequired);
            existing.status = status || (existing.selected >= safeRequired ? 'assigned' : existing.selected > 0 ? 'retrying' : 'pending');
            return;
        }

        vehicleLoadState.rows.push({
            originalName,
            mappedName,
            required: safeRequired,
            selected: Math.min(safeSelected, safeRequired),
            status: status || (safeSelected >= safeRequired ? 'assigned' : safeSelected > 0 ? 'retrying' : 'pending')
        });
    }

    function setVehicleStatus(originalName, status) {
        const row = vehicleLoadState.rows.find(r => r.originalName === originalName);
        if (row) {
            row.status = status;
            row.selected = Math.min(countSelectedMatchingVehicles(row.originalName, row.mappedName), Number(row.required || 0));
        }
    }

    function renderVehicleLoadListNow() {
        const listContent = document.getElementById('vehicle-load-list-content');
        const patientContent = document.getElementById('vehicle-patient-content');
        const summary = document.getElementById('vehicle-load-summary');
        const progress = document.getElementById('vehicle-load-progress');

        if (!listContent || !patientContent || !summary || !progress) return;

        refreshVehicleRequirementCounters();

        const totalRequired = vehicleLoadState.rows.reduce((sum, row) => sum + Number(row.required || 0), 0);
        const foundRequired = vehicleLoadState.rows.reduce((sum, row) => sum + Number(row.selected || 0), 0);

        const percent = totalRequired > 0 ? Math.round((foundRequired / totalRequired) * 100) : vehicleLoadState.ready ? 100 : 0;

        summary.innerHTML = `
            <div>Vehicles: <strong>${foundRequired}</strong> / <strong>${totalRequired}</strong></div>
            <div>Status: <strong class="${vehicleLoadState.ready ? 'mf2026-good' : 'mf2026-warn'}">${vehicleLoadState.ready ? 'Ready' : 'Not Ready'}</strong></div>
        `;

        progress.style.width = `${percent}%`;

        if (vehicleLoadState.rows.length === 0) {
            listContent.innerHTML = vehicleLoadState.ready
                ? `<span class="mf2026-good">✓ Ambulance-only mission ready</span>`
                : `Click Unit Finder to load vehicles.`;
        } else {
            listContent.innerHTML = vehicleLoadState.rows.map(row => {
                let icon = '○';
                let cls = 'mf2026-warn';

                const selected = Math.min(Number(row.selected || 0), Number(row.required || 0));
                const required = Number(row.required || 0);

                if (selected >= required && required > 0) {
                    icon = '✓';
                    cls = 'mf2026-good';
                } else if (row.status === 'missing') {
                    icon = '✕';
                    cls = 'mf2026-bad';
                } else if (selected > 0 || row.status === 'retrying') {
                    icon = '↻';
                    cls = 'mf2026-warn';
                }

                return `
                    <div class="mf2026-row">
                        <div class="mf2026-name">
                            <span class="${cls}">${icon}</span>
                            ${escapeHtml(row.originalName)}
                            <div class="mf2026-small">${escapeHtml(row.mappedName)}</div>
                        </div>
                        <div class="mf2026-count ${selected >= required && required > 0 ? 'mf2026-good' : 'mf2026-warn'}">${selected} / ${required}</div>
                    </div>
                `;
            }).join('');
        }

        patientContent.innerHTML = `
            <div class="mf2026-row">
                <div>Patients found</div>
                <div class="mf2026-count">${vehicleLoadState.patients}</div>
            </div>
            <div class="mf2026-row">
                <div>Ambulances selected</div>
                <div class="mf2026-count">${vehicleLoadState.ambulances}</div>
            </div>
            <div class="mf2026-row">
                <div>Ambulance Officer</div>
                <div class="mf2026-count mf2026-warn">Live requirements only</div>
            </div>
        `;
    }

    function renderVehicleLoadList() {
        if (mfVehicleLoadRenderFrame !== null) return;

        const run = () => {
            mfVehicleLoadRenderFrame = null;
            renderVehicleLoadListNow();
        };

        if (typeof requestAnimationFrame === 'function') {
            mfVehicleLoadRenderFrame = requestAnimationFrame(run);
        } else {
            mfVehicleLoadRenderFrame = setTimeout(run, 50);
        }
    }

    function escapeHtml(value) {
        return String(value)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;');
    }

    function getPatientSelectionMissionKey() {
        const localMissionKey =
            getLocalMissionInstanceKey();

        if (localMissionKey) {
            return localMissionKey;
        }

        const missionId =
            getCurrentMissionIdForQueueRestart();

        if (missionId) {
            return `mission:${missionId}`;
        }

        const missionName =
            String(
                getCurrentMissionName() ||
                'Mission'
            )
                .replace(/\s+/g, ' ')
                .trim();

        return `mission-name:${missionName}`;
    }

    function readPatientSelectionLedger() {
        const missionKey =
            getPatientSelectionMissionKey();

        if (
            mfPatientSelectionLedgerCache &&
            mfPatientSelectionLedgerCache.missionKey ===
                missionKey
        ) {
            return mfPatientSelectionLedgerCache;
        }

        let parsed = null;

        try {
            parsed = JSON.parse(
                sessionStorage.getItem(
                    MF_PATIENT_SELECTION_LEDGER_KEY
                ) ||
                'null'
            );
        } catch (_error) {
            parsed = null;
        }

        if (
            !parsed ||
            parsed.missionKey !== missionKey ||
            !parsed.counts ||
            typeof parsed.counts !== 'object'
        ) {
            parsed = {
                missionKey,
                counts: {}
            };
        }

        mfPatientSelectionLedgerCache = parsed;

        try {
            sessionStorage.setItem(
                MF_PATIENT_SELECTION_LEDGER_KEY,
                JSON.stringify(parsed)
            );
        } catch (_error) {}

        return parsed;
    }

    function savePatientSelectionLedger(ledger) {
        if (!ledger) return;

        mfPatientSelectionLedgerCache = ledger;

        try {
            sessionStorage.setItem(
                MF_PATIENT_SELECTION_LEDGER_KEY,
                JSON.stringify(ledger)
            );
        } catch (_error) {}
    }

    function getTrackedPatientUnitSelections(type) {
        const key =
            String(type || '')
                .trim()
                .toLowerCase();

        if (!key) return 0;

        const ledger =
            readPatientSelectionLedger();

        return Math.max(
            0,
            parseInt(
                ledger.counts[key],
                10
            ) || 0
        );
    }

    function setTrackedPatientUnitSelections(
        type,
        total
    ) {
        const key =
            String(type || '')
                .trim()
                .toLowerCase();

        if (!key) return 0;

        const ledger =
            readPatientSelectionLedger();

        const safeTotal =
            Math.max(
                0,
                parseInt(total, 10) || 0
            );

        ledger.counts[key] =
            Math.max(
                getTrackedPatientUnitSelections(key),
                safeTotal
            );

        savePatientSelectionLedger(ledger);

        return ledger.counts[key];
    }

    function incrementTrackedPatientUnitSelections(
        type,
        amount
    ) {
        const current =
            getTrackedPatientUnitSelections(type);

        const addition =
            Math.max(
                0,
                parseInt(amount, 10) || 0
            );

        return setTrackedPatientUnitSelections(
            type,
            current + addition
        );
    }

    function handlePatientSelector() {
        updateStatusBox('Handling patient ambulance selection...');

        const patientCount = findPatientCount(true);

        if (mfDebugEnabled) {
            debugLog('PATIENTS', `Patient badge count = ${patientCount}`);
        }

        vehicleLoadState.patients = patientCount;
        vehicleLoadState.ambulances = Math.max(
            countSelectedMatchingVehicles(
                'Ambulance',
                'Ambulance x 01'
            ),
            getTrackedPatientUnitSelections(
                'ambulance'
            )
        );
        vehicleLoadState.ambulanceOfficer = false;

        // V9.1: patient badge only sends ambulances.
        // Specialist ambulance units/officers are selected only when the live mission requirements ask for them.
        if (patientCount > 0) {
            triggerAmbulanceClick(patientCount);
        }

        renderVehicleLoadList();

        return patientCount;
    }

    function getActiveMissionScopesForPatients() {
        // Use the same current-mission container resolution as Mission Update.
        // The old selector sweep could retain a visible patient badge/card from
        // the previously opened mission and make Auto Mode send Ambulances on a
        // Police-only mission.
        const contextRoots =
            getActiveMissionRequirementContexts()
                .map(context => context.root)
                .filter(Boolean);

        const currentMissionRoots =
            getCurrentMissionPatientAlertRoots(
                [],
                contextRoots
            );

        const visibleRoots =
            Array.from(
                new Set(
                    currentMissionRoots
                        .filter(root => {
                            if (!root) return false;
                            if (root.nodeType === 9) {
                                return isMissionDocumentVisible(root);
                            }

                            return isMissionElementVisible(root);
                        })
                )
            );

        if (visibleRoots.length > 0) {
            return visibleRoots;
        }

        const missionInfo =
            getActiveVisibleMissionInfo();

        if (missionInfo) {
            const missionContainer =
                missionInfo.closest?.(
                    '.vm--modal, .modal, .lightbox, #lightbox_box, ' +
                    '#iframe-inside-container, #mission_content, .mission_content'
                );

            if (missionContainer) {
                return [missionContainer];
            }

            return [
                missionInfo.ownerDocument ||
                document
            ];
        }

        return /^\/missions\//.test(
            window.location.pathname
        )
            ? [document]
            : [];
    }

    function invalidatePatientCountCache() {
        mfPatientCountCache = {
            expiresAt: 0,
            missionKey: '',
            value: 0
        };
    }

    function findPatientCount(forceRefresh = false) {
        if (!isCurrentMissionExecutionOwner('patient count read')) {
            return 0;
        }

        synchroniseMissionInstanceState('patient count');

        const now = Date.now();
        const missionKey = getLocalMissionInstanceKey();

        if (
            !forceRefresh &&
            missionKey === mfPatientCountCache.missionKey &&
            now < mfPatientCountCache.expiresAt
        ) {
            return mfPatientCountCache.value;
        }

        const value = computePatientCountNow();

        mfPatientCountCache = {
            expiresAt: now + 200,
            missionKey,
            value
        };

        return value;
    }

    function computePatientCountNow() {
        const scopes = getActiveMissionScopesForPatients();
        let highestBadgeCount = 0;

        for (const scope of scopes) {
            const badges = Array.from(scope.querySelectorAll('span.badge, .badge'));

            for (const badge of badges) {
                const text = (badge.textContent || '').replace(/\s+/g, ' ').trim();

                if (!/patients?/i.test(text)) continue;

                const numberMatch = text.match(/\d+/);
                const count = numberMatch ? parseInt(numberMatch[0], 10) : 0;

                if (Number.isFinite(count) && count > highestBadgeCount) {
                    highestBadgeCount = count;
                }
            }
        }

        if (highestBadgeCount > 0) return highestBadgeCount;

        // Some missions create the patient cards before updating the badge.
        // Count the visible patient cards as a second source.
        const patientCards = [];

        scopes.forEach(scope => {
            scope.querySelectorAll('.mission_patient, [id^="patient_"][class*="patient"], .patient').forEach(card => {
                if (patientCards.includes(card)) return;

                try {
                    if (!isElementVisible(card)) return;
                } catch (error) {}

                // Avoid counting tiny labels/icons as complete patient cards.
                const text = (card.innerText || card.textContent || '').replace(/\s+/g, ' ').trim();
                const hasPatientContent =
                    card.classList.contains('mission_patient') ||
                    /patient|we need:|transport/i.test(text) ||
                    !!card.querySelector('.alert, .patient_name, [id^="patient_"]');

                if (hasPatientContent) patientCards.push(card);
            });
        });

        return patientCards.length;
    }

    // Legacy helper kept for live mission requirement support. Patient handling no longer calls this.
    function triggerAmbulanceOfficerClick() {
        const ambulanceOfficer = findUnitButton('Ambulance Officer');

        if (ambulanceOfficer) {
            if (mfDebugEnabled) debugLog('AMBULANCE OFFICER', `Selecting ${getVehicleDebugName(ambulanceOfficer)}`);
            clickVehicleElement(ambulanceOfficer);
            vehicleLoadState.ambulanceOfficer = true;
            renderVehicleLoadList();
        } else if (mfDebugEnabled) {
            debugLog('AMBULANCE OFFICER', 'No Ambulance Officer checkbox/button found');
        }
    }

    // Legacy helper kept for future/manual use only. Mission updates use selectVehicleUnits directly.
    function triggerAmbulanceClick(number) {
        if (mfDebugEnabled) {
            debugLog('AMBULANCE SELECTOR', `Requested ${number} ambulance(s) from patient count`);
        }

        const trackedSelected =
            getTrackedPatientUnitSelections(
                'ambulance'
            );

        const domSelected =
            countSelectedMatchingVehicles(
                'Ambulance',
                'Ambulance x 01'
            );

        const alreadySelected =
            Math.min(
                Math.max(
                    domSelected,
                    trackedSelected
                ),
                number
            );

        const remaining =
            Math.max(
                0,
                number -
                alreadySelected
            );

        addOrUpdateVehicleRow(
            'Ambulance',
            'Ambulance x 01',
            number,
            remaining > 0
                ? 'pending'
                : 'assigned',
            alreadySelected
        );

        renderVehicleLoadList();

        let selectionResult = null;

        if (remaining > 0) {
            selectionResult =
                selectVehicleUnits(
                    'Ambulance',
                    'Ambulance x 01',
                    remaining,
                    'PATIENT'
                );
        }

        const selectedFromDom =
            Math.min(
                countSelectedMatchingVehicles(
                    'Ambulance',
                    'Ambulance x 01'
                ),
                number
            );

        const selectedFromThisAttempt =
            Math.min(
                number,
                alreadySelected +
                Math.max(
                    0,
                    parseInt(
                        selectionResult?.assigned,
                        10
                    ) || 0
                )
            );

        const selectedNow =
            Math.max(
                selectedFromDom,
                selectedFromThisAttempt
            );

        setTrackedPatientUnitSelections(
            'ambulance',
            selectedNow
        );

        addOrUpdateVehicleRow(
            'Ambulance',
            'Ambulance x 01',
            number,
            selectedNow >= number
                ? 'assigned'
                : 'missing',
            selectedNow
        );

        vehicleLoadState.ambulances =
            selectedNow;

        if (mfDebugEnabled) {
            debugLog(
                'AMBULANCE CAP',
                `Required=${number} | DOM selected=${domSelected} | tracked=${trackedSelected} | ` +
                `counted before=${alreadySelected} | clicked at most=${remaining} | final=${selectedNow}`
            );
        }

        renderVehicleLoadList();
    }

    function getMissionIdFromLocalScope(scope) {
        if (!scope) return '';

        const attributeNames = [
            'data-mission-id',
            'data-id',
            'mission_id',
            'data-mission'
        ];

        const attributeElements = [];

        if (scope.nodeType === 1) {
            attributeElements.push(scope);
        }

        try {
            attributeElements.push(
                ...scope.querySelectorAll(
                    '#mission_general_info, [data-mission-id], [mission_id]'
                )
            );
        } catch (_error) {}

        for (const element of attributeElements) {
            for (const attributeName of attributeNames) {
                const value = element?.getAttribute?.(attributeName);

                if (value && /^\d+$/.test(String(value).trim())) {
                    return String(value).trim();
                }
            }
        }

        const urlElements = [];

        try {
            urlElements.push(
                ...scope.querySelectorAll(
                    'a[href*="/missions/"], a[href*="mission_id="], ' +
                    'form[action*="/missions/"], form[action*="mission_id="]'
                )
            );
        } catch (_error) {}

        for (const element of urlElements) {
            const value =
                element?.href ||
                element?.action ||
                element?.getAttribute?.('href') ||
                element?.getAttribute?.('action') ||
                '';

            const missionId =
                parseMissionIdFromHrefForQueueRestart(value);

            if (missionId) return missionId;
        }

        try {
            const input = scope.querySelector(
                'input[name="mission_id"], input#mission_id'
            );

            const inputValue = String(input?.value || '').trim();

            if (/^\d+$/.test(inputValue)) {
                return inputValue;
            }
        } catch (_error) {}

        return '';
    }

    function getLocalMissionInstanceKey() {
        const locationMissionId =
            parseMissionIdFromHrefForQueueRestart(
                window.location.href
            );

        if (locationMissionId) {
            return `mission:${locationMissionId}`;
        }

        const visibleMissionInfo = Array.from(
            document.querySelectorAll('#mission_general_info')
        )
            .filter(element => isMissionElementVisible(element))
            .pop() || null;

        const localScope =
            visibleMissionInfo?.closest?.(
                '#iframe-inside-container, #mission_content, .mission_content, ' +
                '.vm--modal, .modal, .lightbox, #lightbox_box'
            ) ||
            visibleMissionInfo ||
            document;

        const scopedMissionId =
            getMissionIdFromLocalScope(localScope);

        if (scopedMissionId) {
            return `mission:${scopedMissionId}`;
        }

        try {
            const frameSource =
                window.frameElement?.getAttribute?.('src') ||
                window.frameElement?.src ||
                '';

            const frameMissionId =
                parseMissionIdFromHrefForQueueRestart(frameSource);

            if (frameMissionId) {
                return `mission:${frameMissionId}`;
            }
        } catch (_error) {}

        const localHelpLink = Array.from(
            document.querySelectorAll('#mission_help')
        )
            .filter(element => isMissionElementVisible(element))
            .pop() || null;

        const helpHref = String(
            localHelpLink?.getAttribute?.('href') ||
            localHelpLink?.href ||
            ''
        ).trim();

        const missionTitle = String(
            visibleMissionInfo?.getAttribute?.('data-mission-title') ||
            document.querySelector('#missionH1')?.textContent ||
            ''
        )
            .replace(/\s+/g, ' ')
            .trim();

        return [
            'document',
            window.location.pathname,
            window.location.search,
            helpHref,
            missionTitle
        ].join('|');
    }

    function getPrimaryMissionRequirementDocument() {
        const candidates = [];

        getMissionAccessibleDocuments(true)
            .forEach((candidateDocument, documentIndex) => {
                if (
                    !candidateDocument ||
                    !isMissionDocumentVisible(candidateDocument)
                ) {
                    return;
                }

                let score = 0;
                let visibleMarkerCount = 0;

                const markerDefinitions = [
                    ['#mission_general_info', 500],
                    ['#mission_alarm_btn, #alarm_button', 350],
                    ['input.vehicle_checkbox', 250],
                    ['#mission_help', 180]
                ];

                markerDefinitions.forEach(([selector, weight]) => {
                    let visibleCount = 0;

                    try {
                        visibleCount = Array.from(
                            candidateDocument.querySelectorAll(selector)
                        ).filter(element => isMissionElementVisible(element)).length;
                    } catch (_error) {}

                    if (visibleCount > 0) {
                        score += weight;
                        visibleMarkerCount += visibleCount;
                    }
                });

                if (visibleMarkerCount === 0) return;

                try {
                    const frame =
                        candidateDocument.defaultView?.frameElement;

                    if (frame && isMissionElementVisible(frame)) {
                        score += 1000;

                        const ownerDocument = frame.ownerDocument;
                        const ownerWindow =
                            ownerDocument?.defaultView ||
                            window;

                        const ownerModal = frame.closest(
                            '.vm--modal, .modal, .lightbox, #lightbox_box'
                        );

                        if (ownerModal) {
                            const modalStyle =
                                ownerWindow.getComputedStyle(ownerModal);

                            const modalZIndex = parseInt(
                                modalStyle.zIndex,
                                10
                            );

                            if (Number.isFinite(modalZIndex)) {
                                score += Math.max(0, modalZIndex) * 10;
                            }

                            if (
                                ownerModal.getAttribute('aria-modal') === 'true' ||
                                ownerModal.getAttribute('aria-expanded') === 'true'
                            ) {
                                score += 2000;
                            }

                            const allModals = Array.from(
                                ownerDocument.querySelectorAll(
                                    '.vm--modal, .modal, .lightbox, #lightbox_box'
                                )
                            );

                            score += Math.max(
                                0,
                                allModals.indexOf(ownerModal)
                            ) * 20;
                        }

                        const frameStyle =
                            ownerWindow.getComputedStyle(frame);

                        const frameZIndex = parseInt(
                            frameStyle.zIndex,
                            10
                        );

                        if (Number.isFinite(frameZIndex)) {
                            score += Math.max(0, frameZIndex);
                        }

                        const allFrames = Array.from(
                            ownerDocument.querySelectorAll('iframe')
                        );

                        score += Math.max(0, allFrames.indexOf(frame));

                        try {
                            const rect = frame.getBoundingClientRect();
                            const probePoints = [
                                [rect.left + rect.width / 2, rect.top + rect.height / 2],
                                [rect.left + Math.min(30, rect.width / 4), rect.top + Math.min(30, rect.height / 4)],
                                [rect.right - Math.min(30, rect.width / 4), rect.top + Math.min(30, rect.height / 4)]
                            ];

                            const topmostHits = probePoints.filter(([x, y]) => {
                                if (
                                    x < 0 ||
                                    y < 0 ||
                                    x > ownerWindow.innerWidth ||
                                    y > ownerWindow.innerHeight
                                ) {
                                    return false;
                                }

                                const hit = ownerDocument.elementFromPoint(x, y);
                                return hit === frame;
                            }).length;

                            if (topmostHits > 0) {
                                score += 100000 + (topmostHits * 1000);
                            }
                        } catch (_error) {}
                    } else if (
                        candidateDocument ===
                        candidateDocument.defaultView?.top?.document
                    ) {
                        // Direct /missions/... page without an iframe.
                        score += 50000;
                    }
                } catch (_error) {}

                candidates.push({
                    document: candidateDocument,
                    score,
                    documentIndex
                });
            });

        candidates.sort((left, right) => {
            return (
                right.score - left.score ||
                right.documentIndex - left.documentIndex
            );
        });

        return candidates[0]?.document || document;
    }

    function getSharedTopWindow() {
        try {
            return window.top || window;
        } catch (_error) {
            return window;
        }
    }

    function claimCurrentMissionExecutionOwnership(reason = '') {
        const primaryDocument =
            getPrimaryMissionRequirementDocument();

        if (primaryDocument !== document) {
            return false;
        }

        const sharedTopWindow =
            getSharedTopWindow();

        try {
            sharedTopWindow[MF_SHARED_ACTIVE_INSTANCE_KEY] = {
                token: MF_INSTANCE_TOKEN,
                missionKey: getLocalMissionInstanceKey(),
                claimedAt: Date.now(),
                reason: String(reason || '')
            };
        } catch (_error) {}

        return true;
    }

    function isCurrentMissionExecutionOwner(reason = '') {
        const primaryDocument =
            getPrimaryMissionRequirementDocument();

        if (primaryDocument !== document) {
            return false;
        }

        const sharedTopWindow =
            getSharedTopWindow();

        try {
            const owner =
                sharedTopWindow[MF_SHARED_ACTIVE_INSTANCE_KEY];

            if (
                !owner ||
                owner.token === MF_INSTANCE_TOKEN ||
                owner.missionKey !== getLocalMissionInstanceKey() ||
                Date.now() - Number(owner.claimedAt || 0) > 5000
            ) {
                return claimCurrentMissionExecutionOwnership(reason);
            }

            return owner.token === MF_INSTANCE_TOKEN;
        } catch (_error) {
            return true;
        }
    }

    function getCurrentFrameOwnerMissionRoot(primaryDocument) {
        try {
            const frame =
                primaryDocument?.defaultView?.frameElement;

            if (!frame || !isMissionElementVisible(frame)) {
                return null;
            }

            const ownerRoot = frame.closest(
                '.vm--modal, .modal, .lightbox, #lightbox_box'
            );

            return ownerRoot && isMissionElementVisible(ownerRoot)
                ? ownerRoot
                : null;
        } catch (_error) {
            return null;
        }
    }

    function synchroniseMissionInstanceState(reason = '') {
        const nextMissionKey =
            getLocalMissionInstanceKey();

        if (!mfCurrentMissionInstanceKey) {
            mfCurrentMissionInstanceKey = nextMissionKey;
            return false;
        }

        if (
            !nextMissionKey ||
            nextMissionKey === mfCurrentMissionInstanceKey
        ) {
            return false;
        }

        const currentKeyIsStrong =
            /^mission:\d+$/.test(
                mfCurrentMissionInstanceKey
            );

        const nextKeyIsStrong =
            /^mission:\d+$/.test(
                nextMissionKey
            );

        // The mission ID can appear a fraction later than the initial DOM.
        // Promote a provisional document key to the real mission ID without
        // treating that as a second mission and clearing valid selections.
        if (!currentKeyIsStrong && nextKeyIsStrong) {
            mfCurrentMissionInstanceKey = nextMissionKey;
            invalidateMissionContextCaches();
            invalidatePatientCountCache();
            return false;
        }

        // Do not demote a known mission ID during a brief partial render.
        if (currentKeyIsStrong && !nextKeyIsStrong) {
            return false;
        }

        mfCurrentMissionInstanceKey = nextMissionKey;

        invalidateMissionContextCaches();
        invalidatePatientCountCache();
        invalidateVehicleCheckboxCache();
        clearSelectionGuards();
        clearAutoSelectionMissionGuard(
            `mission changed: ${reason || 'shared reader'}`
        );

        mfPatientSelectionLedgerCache = null;

        try {
            sessionStorage.removeItem(
                MF_PATIENT_SELECTION_LEDGER_KEY
            );
        } catch (_error) {}

        mfStaffingBlockActive = false;
        mfStaffingBlockText = '';
        mfStaffingBlockMissionKey = '';
        mfMissionUpdateFirstPassMissionKey = '';
        mfMissionUpdateFirstPassRequired = true;
        mfMissionUpdateFirstPassCompletedAt = 0;

        vehicleLoadState = {
            rows: [],
            patients: 0,
            ambulances: 0,
            ambulanceOfficer: false,
            ready: false
        };

        renderVehicleLoadList();

        return true;
    }

    function invalidateMissionContextCaches() {
        mfMissionDocumentCache = {
            expiresAt: 0,
            documents: []
        };

        mfMissionContextCache = {
            expiresAt: 0,
            missionKey: '',
            contexts: []
        };

        mfDispatchReadinessExpensiveCache = {
            expiresAt: 0,
            updateRowsSignature: '',
            staffingText: ''
        };

        mfMissionUpdateRowsCache = {
            expiresAt: 0,
            missionKey: '',
            rows: []
        };
    }

    function isCachedMissionDocumentUsable(candidateDocument) {
        if (!candidateDocument?.documentElement) return false;

        try {
            const ownerWindow = candidateDocument.defaultView;

            if (ownerWindow && ownerWindow.document !== candidateDocument) {
                return false;
            }

            const frame = ownerWindow?.frameElement;
            return !frame || frame.isConnected !== false;
        } catch (_error) {
            return true;
        }
    }

    function getMissionAccessibleDocuments(forceRefresh = false) {
        const now = Date.now();
        const cachedDocuments = mfMissionDocumentCache.documents;

        if (
            !forceRefresh &&
            now < mfMissionDocumentCache.expiresAt &&
            cachedDocuments.every(isCachedMissionDocumentUsable)
        ) {
            return cachedDocuments;
        }

        const documents = [];

        const addDocument = candidate => {
            try {
                if (
                    candidate &&
                    candidate.documentElement &&
                    !documents.includes(candidate)
                ) {
                    documents.push(candidate);
                }
            } catch (_error) {}
        };

        addDocument(document);

        try {
            addDocument(window.parent?.document);
        } catch (_error) {}

        try {
            addDocument(window.top?.document);
        } catch (_error) {}

        let scanIndex = 0;

        while (scanIndex < documents.length) {
            const ownerDocument = documents[scanIndex];
            scanIndex += 1;

            try {
                ownerDocument.querySelectorAll('iframe').forEach(frame => {
                    try {
                        addDocument(
                            frame.contentDocument ||
                            frame.contentWindow?.document
                        );
                    } catch (_error) {}
                });
            } catch (_error) {}
        }

        mfMissionDocumentCache = {
            expiresAt: now + 500,
            documents
        };

        return documents;
    }

    function isMissionElementVisible(
        element
    ) {
        if (
            !element ||
            element.isConnected === false
        ) {
            return false;
        }

        try {
            const ownerDocument =
                element.ownerDocument;

            const ownerWindow =
                ownerDocument
                    ?.defaultView ||
                window;

            const style =
                ownerWindow
                    .getComputedStyle(
                        element
                    );

            if (
                style.display ===
                    'none' ||
                style.visibility ===
                    'hidden' ||
                Number(
                    style.opacity
                ) === 0
            ) {
                return false;
            }

            const rect =
                element
                    .getBoundingClientRect();

            if (
                rect.width <= 0 ||
                rect.height <= 0
            ) {
                return false;
            }

            const frame =
                ownerWindow
                    .frameElement;

            if (
                frame &&
                !isMissionElementVisible(
                    frame
                )
            ) {
                return false;
            }

            return true;
        } catch (_error) {
            try {
                return !!(
                    element.offsetWidth ||
                    element.offsetHeight ||
                    element
                        .getClientRects()
                        .length
                );
            } catch (_innerError) {
                return false;
            }
        }
    }

    function isMissionDocumentVisible(
        candidateDocument
    ) {
        if (!candidateDocument) {
            return false;
        }

        try {
            const frame =
                candidateDocument
                    .defaultView
                    ?.frameElement;

            if (
                frame &&
                !isMissionElementVisible(
                    frame
                )
            ) {
                return false;
            }
        } catch (_error) {}

        return true;
    }

    function getMissionContextRootForMarker(
        marker
    ) {
        if (
            !marker ||
            !marker.ownerDocument
        ) {
            return null;
        }

        const outerWindow =
            marker.closest?.(
                '.vm--modal, .modal, .lightbox, #lightbox_box'
            );

        if (outerWindow) {
            return outerWindow;
        }

        const contentRoot =
            marker.closest?.(
                '#mc-map-command-toolkit-mission-requirements, ' +
                '[data-mcms-requirements-panel="1"], ' +
                '#iframe-inside-container, #mission_content, .mission_content'
            );

        if (contentRoot) {
            return contentRoot;
        }

        return marker.ownerDocument;
    }

    function getActiveMissionRequirementContexts(forceRefresh = false) {
        const now = Date.now();
        const missionKey = getLocalMissionInstanceKey();
        const cachedContexts = mfMissionContextCache.contexts;
        const cacheStillConnected = cachedContexts.every(context => {
            const root = context?.root;

            if (!root) return false;
            if (root.nodeType === 9) return isCachedMissionDocumentUsable(root);
            return root.isConnected !== false;
        });

        if (
            !forceRefresh &&
            missionKey === mfMissionContextCache.missionKey &&
            now < mfMissionContextCache.expiresAt &&
            cacheStillConnected
        ) {
            return cachedContexts;
        }

        const contexts = buildActiveMissionRequirementContexts();

        mfMissionContextCache = {
            expiresAt: now + 300,
            missionKey,
            contexts
        };

        return contexts;
    }

    function buildActiveMissionRequirementContexts() {
        const contexts =
            new Map();

        const addContext =
            (
                root,
                score,
                reason
            ) => {
                if (!root) return;

                const ownerDocument =
                    root.nodeType ===
                        9
                        ? root
                        : root
                            .ownerDocument;

                if (
                    !ownerDocument ||
                    !isMissionDocumentVisible(
                        ownerDocument
                    )
                ) {
                    return;
                }

                if (
                    root.nodeType !==
                        9 &&
                    !isMissionElementVisible(
                        root
                    )
                ) {
                    return;
                }

                const existing =
                    contexts.get(
                        root
                    );

                if (existing) {
                    existing.score =
                        Math.max(
                            existing.score,
                            score
                        );

                    if (
                        reason &&
                        !existing
                            .reasons
                            .includes(
                                reason
                            )
                    ) {
                        existing
                            .reasons
                            .push(
                                reason
                            );
                    }

                    return;
                }

                contexts.set(
                    root,
                    {
                        root,
                        document:
                            ownerDocument,
                        score,
                        reasons:
                            reason
                                ? [
                                    reason
                                ]
                                : []
                    }
                );
            };

        const primaryMissionDocument =
            getPrimaryMissionRequirementDocument();

        const accessibleDocuments =
            primaryMissionDocument
                ? [primaryMissionDocument]
                : [document];

        accessibleDocuments
            .forEach(
                candidateDocument => {
                    if (
                        !isMissionDocumentVisible(
                            candidateDocument
                        )
                    ) {
                        return;
                    }

                    const contextCountBeforeDocument = contexts.size;

                    const markerDefinitions = [
                        {
                            selector:
                                '#mission_general_info',
                            score:
                                120,
                            reason:
                                'mission-general-info'
                        },
                        {
                            selector:
                                '#mission_alarm_btn, #alarm_button',
                            score:
                                100,
                            reason:
                                'dispatch-button'
                        },
                        {
                            selector:
                                'input.vehicle_checkbox, input[type="checkbox"][vehicle_id]',
                            score:
                                80,
                            reason:
                                'vehicle-list'
                        },
                        {
                            selector:
                                '#mission_help',
                            score:
                                50,
                            reason:
                                'mission-help'
                        },
                        {
                            selector:
                                '#mc-map-command-toolkit-mission-requirements[data-mcms-requirements-panel="1"], ' +
                                'section[data-mcms-requirements-panel="1"] table[aria-label="Live mission requirements"]',
                            score:
                                115,
                            reason:
                                'live-requirements-panel'
                        },
                        {
                            selector:
                                '.alert.alert-danger, .alert-danger, [role="alert"], [id*="missing_"], [class*="missing"]',
                            score:
                                90,
                            reason:
                                'mission-alert'
                        }
                    ];

                    markerDefinitions
                        .forEach(
                            definition => {
                                let elements = [];

                                try {
                                    elements =
                                        Array.from(
                                            candidateDocument
                                                .querySelectorAll(
                                                    definition
                                                        .selector
                                                )
                                        );
                                } catch (_error) {}

                                elements
                                    .forEach(
                                        element => {
                                            if (
                                                !isMissionElementVisible(
                                                    element
                                                )
                                            ) {
                                                return;
                                            }

                                            if (
                                                definition.reason ===
                                                    'mission-alert'
                                            ) {
                                                const value =
                                                    (
                                                        element
                                                            .innerText ||
                                                        element
                                                            .textContent ||
                                                        ''
                                                    )
                                                        .replace(
                                                            /\s+/g,
                                                            ' '
                                                        )
                                                        .trim();

                                                if (
                                                    !/Missing\s+(?:Vehicles?|Personnel):|We\s+need\s*:/i
                                                        .test(
                                                            value
                                                        )
                                                ) {
                                                    return;
                                                }
                                            }

                                            addContext(
                                                getMissionContextRootForMarker(
                                                    element
                                                ),
                                                definition
                                                    .score,
                                                definition
                                                    .reason
                                            );
                                        }
                                    );
                            }
                        );

                    // A visible outer mission modal may contain the update
                    // alert outside the inner mission-content element. Only
                    // scan complete modal text when the precise markers above
                    // did not already identify a mission context.
                    if (contexts.size === contextCountBeforeDocument) try {
                        candidateDocument
                            .querySelectorAll(
                                '.vm--modal, .modal, .lightbox, #lightbox_box'
                            )
                            .forEach(
                                container => {
                                    if (
                                        !isMissionElementVisible(
                                            container
                                        )
                                    ) {
                                        return;
                                    }

                                    const value =
                                        (
                                            container
                                                .innerText ||
                                            container
                                                .textContent ||
                                            ''
                                        )
                                            .replace(
                                                /\s+/g,
                                                ' '
                                            )
                                            .trim();

                                    const hasMissionMarker =
                                        !!container
                                            .querySelector(
                                                '#mission_general_info, #mission_alarm_btn, #alarm_button, input.vehicle_checkbox, #mission_help'
                                            );

                                    const hasUpdateText =
                                        /Missing\s+(?:Vehicles?|Personnel):|We\s+need\s*:/i
                                            .test(
                                                value
                                            );

                                    if (
                                        hasMissionMarker ||
                                        hasUpdateText
                                    ) {
                                        addContext(
                                            container,
                                            hasUpdateText
                                                ? 110
                                                : 70,
                                            hasUpdateText
                                                ? 'outer-update-window'
                                                : 'outer-mission-window'
                                        );
                                    }
                                }
                            );
                    } catch (_error) {}

                    // Last-resort document-wide text probe. Avoid reading the
                    // complete body when strong mission markers already produced
                    // a context for this document.
                    if (contexts.size === contextCountBeforeDocument) try {
                        const bodyValue =
                            (
                                candidateDocument
                                    .body
                                    ?.innerText ||
                                candidateDocument
                                    .body
                                    ?.textContent ||
                                ''
                            )
                                .replace(
                                    /\s+/g,
                                    ' '
                                )
                                .trim();

                        const hasMissionControls =
                            !!candidateDocument
                                .querySelector(
                                    '#mission_alarm_btn, #alarm_button, input.vehicle_checkbox, #mission_general_info'
                                );

                        const hasExplicitUpdate =
                            /Missing\s+(?:Vehicles?|Personnel):|We\s+need\s*:/i
                                .test(
                                    bodyValue
                                );

                        if (
                            hasMissionControls ||
                            hasExplicitUpdate
                        ) {
                            addContext(
                                candidateDocument,
                                hasExplicitUpdate
                                    ? 60
                                    : 30,
                                hasExplicitUpdate
                                    ? 'document-update-text'
                                    : 'document-mission-controls'
                            );
                        }
                    } catch (_error) {}
                }
            );

        const currentFrameOwnerRoot =
            getCurrentFrameOwnerMissionRoot(
                primaryMissionDocument
            );

        if (currentFrameOwnerRoot) {
            addContext(
                currentFrameOwnerRoot,
                125,
                'current-frame-owner-modal'
            );
        }

        if (
            contexts.size ===
            0
        ) {
            addContext(
                document,
                0,
                'current-document-fallback'
            );
        }

        return Array.from(
            contexts.values()
        ).sort(
            (
                left,
                right
            ) =>
                right.score -
                left.score
        );
    }

    function getActiveVisibleMissionInfo() {
        const contexts =
            getActiveMissionRequirementContexts();

        for (
            const context of
            contexts
        ) {
            const candidates =
                Array.from(
                    context.root
                        .querySelectorAll(
                            '#mission_general_info'
                        )
                );

            const visible =
                candidates.filter(
                    element =>
                        isMissionElementVisible(
                            element
                        )
                );

            if (
                visible.length >
                0
            ) {
                return visible[
                    visible.length -
                    1
                ];
            }
        }

        return null;
    }

    function getActiveMissionRequirementScope() {
        return (
            getActiveMissionRequirementContexts()[
                0
            ]?.root ||
            document
        );
    }

    function getActiveMissionHelpLink() {
        const contexts =
            getActiveMissionRequirementContexts();

        let scopedCount = 0;

        for (
            const context of
            contexts
        ) {
            const candidates =
                Array.from(
                    context.root
                        .querySelectorAll(
                            '#mission_help'
                        )
                );

            scopedCount +=
                candidates.length;

            const visible =
                candidates.filter(
                    element =>
                        isMissionElementVisible(
                            element
                        )
                );

            if (
                visible.length >
                0
            ) {
                const helpLink =
                    visible[
                        visible.length -
                        1
                    ];

                if (
                    mfDebugEnabled
                ) {
                    debugLog(
                        'LIVE HELP GUARD',
                        `Found active #mission_help in ${context.document.URL || 'unknown document'} | scope=${context.reasons.join(',')}`
                    );
                }

                return helpLink;
            }
        }

        if (mfDebugEnabled) {
            debugLog(
                'LIVE HELP GUARD',
                `No visible #mission_help across ${contexts.length} mission context(s); inspected ${scopedCount} candidate(s).`
            );
        }

        return null;
    }

    function getActiveMissionProblemTextBlocks(
        suppliedRoots
    ) {
        const roots =
            Array.isArray(
                suppliedRoots
            )
                ? suppliedRoots
                : suppliedRoots
                    ? [
                        suppliedRoots
                    ]
                    : getActiveMissionRequirementContexts()
                        .map(
                            context =>
                                context.root
                        );

        const uniqueRoots =
            Array.from(
                new Set(
                    roots.filter(
                        Boolean
                    )
                )
            );

        const exactElements = [];

        uniqueRoots
            .forEach(root => {
                try {
                    root.querySelectorAll(
                        '.alert.alert-danger, .alert-danger, .alert, ' +
                        '[role="alert"], [id*="missing_"], ' +
                        '[id^="alert_danger_"], [class*="missing"], ' +
                        '.mission_update, .mission_update_info'
                    ).forEach(
                        element => {
                            if (
                                !exactElements.includes(
                                    element
                                )
                            ) {
                                exactElements.push(
                                    element
                                );
                            }
                        }
                    );
                } catch (_error) {}
            });

        const exactTexts =
            Array.from(
                new Set(
                    exactElements
                        .filter(
                            element => {
                                if (
                                    !isMissionElementVisible(
                                        element
                                    )
                                ) {
                                    return false;
                                }

                                const value =
                                    (
                                        element
                                            .innerText ||
                                        element
                                            .textContent ||
                                        ''
                                    )
                                        .replace(
                                            /\s+/g,
                                            ' '
                                        )
                                        .trim();

                                return /Missing\s+(?:Vehicles?|Personnel):|We\s+need\s*:/i
                                    .test(
                                        value
                                    );
                            }
                        )
                        .map(element => {
                            return (
                                element
                                    .innerText ||
                                element
                                    .textContent ||
                                ''
                            )
                                .replace(
                                    /\s+/g,
                                    ' '
                                )
                                .trim();
                        })
                        .filter(Boolean)
                )
            );

        if (
            exactTexts.length >
            0
        ) {
            return exactTexts;
        }

        const fallbackElements = [];

        uniqueRoots
            .forEach(root => {
                try {
                    root.querySelectorAll(
                        'div, span, p, li, td, th, strong, b, ' +
                        'section, article, label, small'
                    ).forEach(
                        element => {
                            if (
                                !fallbackElements
                                    .includes(
                                        element
                                    )
                            ) {
                                fallbackElements
                                    .push(
                                        element
                                    );
                            }
                        }
                    );
                } catch (_error) {}
            });

        const fallbackTexts =
            fallbackElements
                .filter(element => {
                    if (
                        !isMissionElementVisible(
                            element
                        )
                    ) {
                        return false;
                    }

                    const value =
                        (
                            element
                                .innerText ||
                            element
                                .textContent ||
                            ''
                        )
                            .replace(
                                /\s+/g,
                                ' '
                            )
                            .trim();

                    if (
                        !/Missing\s+(?:Vehicles?|Personnel):|We\s+need\s*:/i
                            .test(
                                value
                            )
                    ) {
                        return false;
                    }

                    // Keep the smallest matching visible element.
                    return !Array.from(
                        element.children ||
                        []
                    ).some(child => {
                        if (
                            !isMissionElementVisible(
                                child
                            )
                        ) {
                            return false;
                        }

                        const childValue =
                            (
                                child
                                    .innerText ||
                                child
                                    .textContent ||
                                ''
                            )
                                .replace(
                                    /\s+/g,
                                    ' '
                                )
                                .trim();

                        return /Missing\s+(?:Vehicles?|Personnel):|We\s+need\s*:/i
                            .test(
                                childValue
                            );
                    });
                })
                .map(element => {
                    return (
                        element.innerText ||
                        element.textContent ||
                        ''
                    )
                        .replace(
                            /\s+/g,
                            ' '
                        )
                        .trim();
                })
                .filter(Boolean);

        return Array.from(
            new Set(
                fallbackTexts
            )
        );
    }

    function getMissionHelpUrl() {
        const helpLink =
            getActiveMissionHelpLink();

        if (!helpLink) {
            return null;
        }

        const href =
            helpLink.href ||
            helpLink.getAttribute(
                'href'
            ) ||
            '';

        if (
            !href ||
            /^javascript:/i.test(
                href
            )
        ) {
            return null;
        }

        if (mfDebugEnabled) {
            debugLog(
                'LIVE HELP GUARD',
                `Using active visible mission help: ${href}`
            );
        }

        return href;
    }

    function cleanRequirementName(value) {
        return String(value || '')
            .replace(/\s+/g, ' ')
            .replace(/^Required\s+/i, '')
            .replace(/\s+only required.*$/i, '')
            .replace(/\s*\(\s*\d+\s*%\s*\)\s*$/i, '')
            .trim();
    }

    // V10.6.56: MissionChief help/update tables can contain threshold or
    // prerequisite statistics such as "Required minimum policemen 10".
    // These describe the mission generation/minimum staffing threshold; they
    // are not a vehicle or live shortage to dispatch. Keep this as one shared
    // guard so Unit Finder, Mission Update, visible fallback and Auto Mode all
    // ignore the same rows.
    function shouldIgnoreRequiredMinimumRequirement(value) {
        const raw = String(value || '')
            .replace(/\s+/g, ' ')
            .trim();

        if (!raw) return false;

        const withoutRequired = raw
            .replace(/^Required\s+/i, '')
            .trim();

        return /^(?:minimum|min\.?)\b/i.test(withoutRequired);
    }

    // V10.6.40 SAR personnel conversion registry.
    // V10.6.68: Search Advisor now follows the dedicated SARTEC selector.
    // It retains the established two Search Advisors per vehicle conversion,
    // but resolves through the exact displayed-name-prefix SARTEC rule.
    // V10.6.66 restores the established two-Inspector-per-IRV rule and live-verifies Inspector bindings when the shared registry is missing or stale.
    // Police Sergeant is grouped with
    // Level 1 and Level 2, using the highest personnel requirement only.
    // This is used by both Unit Finder and Mission Update so the same
    // personnel requirement always resolves to the same vehicle quantity.
    function getSarPersonnelVehicleRequirement(
        requirementName,
        personnelAmount
    ) {
        const cleanedName =
            cleanRequirementName(
                requirementName
            );

        const amountMatch =
            String(
                personnelAmount ??
                ''
            )
                .replace(
                    /,/g,
                    ''
                )
                .match(
                    /\d+/
                );

        const personnelRequired =
            amountMatch
                ? parseInt(
                    amountMatch[0],
                    10
                )
                : 0;

        if (
            !cleanedName ||
            !Number.isFinite(
                personnelRequired
            ) ||
            personnelRequired <= 0
        ) {
            return null;
        }

        const definitions = [
            {
                pattern:
                    /^search\s+technician(?:s)?$/i,
                personnelLabel:
                    'Search Technician',
                unitName:
                    'SARTEC',
                personnelPerVehicle:
                    4
            },
            {
                pattern:
                    /^search\s+advisor(?:s)?$/i,
                personnelLabel:
                    'Search Advisor',
                unitName:
                    'SARTEC',
                personnelPerVehicle:
                    2
            },
            {
                pattern:
                    /^sar\s+commander(?:s)?$/i,
                personnelLabel:
                    'SAR Commander',
                unitName:
                    'Control Van',
                personnelPerVehicle:
                    2
            }
        ];

        const definition =
            definitions.find(item =>
                item.pattern.test(
                    cleanedName
                )
            );

        if (!definition) {
            return null;
        }

        const vehicleRequired =
            Math.ceil(
                personnelRequired /
                definition.personnelPerVehicle
            );

        return {
            sourceName:
                cleanedName,
            personnelRequired,
            personnelRequirement:
                `${personnelRequired} ${definition.personnelLabel}${personnelRequired === 1 ? '' : 's'}`,
            personnelPerVehicle:
                definition.personnelPerVehicle,
            unitName:
                definition.unitName,
            stillNeeded:
                vehicleRequired
        };
    }

    function getMissingPersonnelSegment(
        text
    ) {
        const input =
            String(
                text ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        const marker =
            /Missing\s+Personnel\s*:/i.exec(
                input
            );

        if (!marker) {
            return '';
        }

        return input
            .slice(
                marker.index +
                marker[0].length
            )
            .replace(
                /\s+(?:Missing\s+Vehicles?|We\s+need)\s*:.+$/i,
                ''
            )
            .trim();
    }

    function getNamedPersonnelCount(
        personnelSegment,
        namePatternSource
    ) {
        const segment =
            String(
                personnelSegment ||
                ''
            );

        if (
            !segment ||
            !namePatternSource
        ) {
            return 0;
        }

        const pattern =
            new RegExp(
                `(?:\\b(\\d+)\\s*(?:x\\s*)?${namePatternSource}\\b|\\b${namePatternSource}\\b\\s*(?:x\\s*)?(\\d+))`,
                'gi'
            );

        let maximum = 0;
        let match;

        while (
            (
                match =
                    pattern.exec(
                        segment
                    )
            )
        ) {
            maximum =
                Math.max(
                    maximum,
                    parseInt(
                        match[1] ||
                        match[2],
                        10
                    ) ||
                    0
                );
        }

        return maximum;
    }

    function shouldSkipLiveRequirement(name, value) {
        const cleanedName = cleanRequirementName(name);
        const text = `${cleanedName} ${value}`.toLowerCase();
        const mappedName = resolveUnitName(cleanedName);

        if (!cleanedName) return true;
        if (shouldIgnoreRequiredMinimumRequirement(name) ||
            shouldIgnoreRequiredMinimumRequirement(cleanedName)) return true;
        if (!/^\d+$/.test(String(value || '').trim())) return true;

        // V9.0.4: Ambulances are selected from the patient badge first, not from the live mission help table.
        // Mission Update still handles later patient-specific ambulance requests.
        if (normaliseVehicleText(mappedName) === normaliseVehicleText('Ambulance x 01')) return true;

        // V9.2.7: these are mission stats/preconditions, not vehicles to send.
        // Example: Domestic flooding (Large) has "Min. Pump Capacity = 1000".
        // That is litres/min pump capacity, NOT Pump x1000.
        if (/^min\.?\s*pump\s*capacity$/i.test(cleanedName)) return true;
        if (/^minimum\s*pump\s*capacity$/i.test(cleanedName)) return true;
        if (/^pump\s*capacity$/i.test(cleanedName)) return true;
        if (/^water\s*to\s*pump$/i.test(cleanedName)) return true;
        if (/water\s*damage\s*pump\s*extension/i.test(cleanedName)) return true;
        if (/\bextension\b/i.test(cleanedName) && !/vehicle|unit|officer|car|engine|pump$/i.test(cleanedName)) return true;

        if (/only required/.test(text)) return true;
        if (/^probability of /i.test(cleanedName)) return true;
        if (/\bprobability\b/.test(text)) return true;
        if (/personnel/.test(text)) return true;
        if (/patients?/.test(text)) return true;
        if (/prisoners?/.test(text)) return true;
        if (/transport request/.test(text)) return true;
        if (/chance/.test(text)) return true;

        return false;
    }

    function extractLiveMissionRequirementRows(html) {
        const doc = new DOMParser().parseFromString(html, 'text/html');

        const candidateTables =
            Array.from(
                doc.querySelectorAll(
                    'table.table, table'
                )
            );

        const table =
            candidateTables.find(tbl => {
                const headings =
                    Array.from(
                        tbl.querySelectorAll(
                            'thead th, thead td'
                        )
                    )
                        .map(cell => {
                            return (
                                cell.textContent ||
                                ''
                            )
                                .replace(
                                    /\s+/g,
                                    ' '
                                )
                                .trim();
                        });

                return headings.some(
                    heading =>
                        /^Vehicle and Personnel Requirements$/i
                            .test(
                                heading
                            )
                );
            }) ||
            candidateTables.find(tbl => {
                const firstHeading =
                    (
                        tbl.querySelector(
                            'th'
                        )?.textContent ||
                        ''
                    )
                        .replace(
                            /\s+/g,
                            ' '
                        )
                        .trim();

                return /^Vehicle and Personnel Requirements$/i
                    .test(
                        firstHeading
                    );
            });

        if (
            mfDebugEnabled
        ) {
            debugLog(
                'UNIT FINDER ATTACHMENT TABLE',
                table
                    ? 'Found exact Vehicle and Personnel Requirements table.'
                    : `No exact Vehicle and Personnel Requirements table found among ${candidateTables.length} table(s).`
            );
        }

        const rows = [];

        if (table) {
            table.querySelectorAll('tbody tr, tr').forEach(tr => {
                const cells = Array.from(tr.querySelectorAll('td')).map(td => td.textContent.replace(/\s+/g, ' ').trim());
                if (cells.length < 2) return;

                const rawRequirementName = cells[0];
                const originalName = cleanRequirementName(rawRequirementName);
                const amountText = cells[1].replace(/\s+/g, ' ').trim();

                if (
                    shouldIgnoreRequiredMinimumRequirement(rawRequirementName) ||
                    shouldIgnoreRequiredMinimumRequirement(originalName)
                ) {
                    return;
                }

                if (mfDebugEnabled) {
                    debugLog(
                        'UNIT FINDER ATTACHMENT ROW',
                        `${originalName || '(blank)'} | value=${amountText}`
                    );
                }

                const towRequirement =
                    getCarsToTowVehicleRequirement(
                        originalName,
                        amountText
                    );

                if (towRequirement) {
                    rows.push({
                        unitName:
                            towRequirement.unitName,
                        stillNeeded:
                            towRequirement.stillNeeded,
                        towCarsRequired:
                            towRequirement.carsRequired
                    });

                    return;
                }

                if (
                    isPoliceInspectorPersonnelRequirementName(
                        originalName
                    )
                ) {
                    const inspectorRequired =
                        Math.max(
                            0,
                            parseInt(
                                amountText,
                                10
                            ) || 0
                        );

                    const inspectorRequirements =
                        normalisePublicOrderTrainedRequirements([
                            {
                                code:
                                    'police_inspector',
                                label:
                                    'Police Inspector',
                                required:
                                    inspectorRequired
                            }
                        ]);

                    if (
                        inspectorRequirements.length >
                        0
                    ) {
                        rows.push({
                            unitName:
                                MF_TRAINED_PERSONNEL_ROW_NAME,
                            stillNeeded:
                                getTrainedPersonnelVehicleTarget(
                                    inspectorRequirements
                                ),
                            isTrainedPersonnelRequirement:
                                true,
                            personnelTrainingRequirements:
                                inspectorRequirements
                        });
                    }

                    return;
                }

                const armedResponseRequirements =
                    getArmedResponsePersonnelRequirements(
                        originalName,
                        amountText
                    );

                if (
                    armedResponseRequirements.length >
                    0
                ) {
                    rows.push({
                        unitName:
                            MF_TRAINED_PERSONNEL_ROW_NAME,
                        stillNeeded:
                            getTrainedPersonnelVehicleTarget(
                                armedResponseRequirements
                            ),
                        isTrainedPersonnelRequirement:
                            true,
                        personnelTrainingRequirements:
                            armedResponseRequirements
                    });

                    if (mfDebugEnabled) {
                        debugLog(
                            'UNIT FINDER ARMED PERSONNEL',
                            `${originalName} x${amountText} -> exact type-25 Armed Traffic Car selection | ${formatTrainedPersonnelRequirements(armedResponseRequirements)}`
                        );
                    }

                    return;
                }

                const sarPersonnelConversion =
                    getSarPersonnelVehicleRequirement(
                        originalName,
                        amountText
                    );

                if (sarPersonnelConversion) {
                    rows.push({
                        unitName:
                            sarPersonnelConversion.unitName,
                        stillNeeded:
                            sarPersonnelConversion.stillNeeded,
                        personnelRequirement:
                            sarPersonnelConversion.personnelRequirement
                    });

                    if (mfDebugEnabled) {
                        debugLog(
                            'UNIT FINDER SAR PERSONNEL',
                            `${sarPersonnelConversion.personnelRequirement} -> ${sarPersonnelConversion.unitName} x${sarPersonnelConversion.stillNeeded} (${sarPersonnelConversion.personnelPerVehicle} personnel per vehicle)`
                        );
                    }

                    return;
                }

                if (shouldSkipLiveRequirement(originalName, amountText)) {
                    if (
                        mfDebugEnabled
                    ) {
                        debugLog(
                            'UNIT FINDER ATTACHMENT SKIP',
                            `${originalName || '(blank)'} | value=${amountText}`
                        );
                    }
                    return;
                }

                const stillNeeded = parseInt(amountText, 10);
                if (!Number.isFinite(stillNeeded) || stillNeeded <= 0) return;

                rows.push({
                    unitName: originalName,
                    stillNeeded
                });

                if (mfDebugEnabled) {
                    debugLog(
                        'UNIT FINDER ATTACHMENT ACCEPT',
                        `${originalName} x${stillNeeded} -> ${resolveUnitName(originalName)}`
                    );
                }
            });
        }

        extractTowCarRequirementRows(doc).forEach(row => rows.push(row));

        return mergeRequirementRows(rows);
    }

    function extractTowCarRequirementRows(doc) {
        const rows = [];
        let maximumCarsToTow = 0;

        doc.querySelectorAll('table.table, table').forEach(table => {
            table.querySelectorAll('tbody tr, tr').forEach(tr => {
                const cells = Array.from(tr.querySelectorAll('td')).map(td => td.textContent.replace(/\s+/g, ' ').trim());
                if (cells.length < 2) return;

                const label = cleanRequirementName(cells[0]);
                const valueText = cells[1].replace(/\s+/g, ' ').trim();

                if (!/^Maximum amount of cars to tow$/i.test(label)) return;

                const cars = parseInt(valueText, 10);
                if (Number.isFinite(cars) && cars > maximumCarsToTow) {
                    maximumCarsToTow = cars;
                }
            });
        });

        if (maximumCarsToTow > 0) {
            // The user's fleet uses the larger flatbed recovery vehicle, which can tow 2 cars.
            // 1-2 cars = 1 flatbed, 3-4 cars = 2 flatbeds, etc.
            const flatbedsNeeded = Math.ceil(maximumCarsToTow / 2);

            rows.push({
                unitName: 'Cars to tow',
                stillNeeded: flatbedsNeeded
            });

            if (mfDebugEnabled) {
                debugLog('LIVE TOW', `Maximum cars to tow=${maximumCarsToTow} -> Flatbed Recovery Vehicle x${flatbedsNeeded}`);
            }
        }

        return rows;
    }

    function isCarsToTowRequirementName(value) {
        const cleaned = String(value || '')
            .replace(/\s+/g, ' ')
            .trim();

        return /^(?:Required\s+)?(?:\d+\s+)?car(?:s)?\s+to\s+tow$/i.test(cleaned) ||
            /^(?:Required\s+)?(?:Maximum|Minimum)\s+amount\s+of\s+cars\s+to\s+tow$/i.test(cleaned);
    }

    function getCarsToTowVehicleRequirement(unitName, carsRequired) {
        if (!isCarsToTowRequirementName(unitName)) {
            return null;
        }

        const embeddedCount = String(unitName || '')
            .replace(/,/g, '')
            .match(/^(?:Required\s+)?(\d+)\s+car(?:s)?\s+to\s+tow$/i);

        const amountMatch = String(
            embeddedCount ? embeddedCount[1] : (carsRequired ?? '')
        )
            .replace(/,/g, '')
            .match(/\d+/);

        const cars = amountMatch
            ? Math.max(0, parseInt(amountMatch[0], 10) || 0)
            : 0;

        if (cars <= 0) {
            return null;
        }

        return {
            unitName: 'Cars to tow',
            carsRequired: cars,
            stillNeeded: Math.ceil(cars / 2)
        };
    }


    function normaliseVehicleRequirementCount(
        originalName,
        mappedName,
        amount
    ) {
        const required =
            Math.max(
                0,
                parseInt(
                    amount,
                    10
                ) || 0
            );

        const raw =
            String(
                originalName || ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        if (
            /^(?:Required\s+)?Firefighters?$/i.test(
                raw
            ) &&
            normaliseVehicleText(
                mappedName
            ) ===
                'rescue pump'
        ) {
            return Math.ceil(
                required /
                9
            );
        }

        return required;
    }

    function mergeRequirementRows(rows) {
        const merged =
            new Map();

        rows.forEach(row => {
            if (shouldIgnoreRequiredMinimumRequirement(row?.unitName)) {
                return;
            }

            if (
                row?.isTrainedPersonnelRequirement
            ) {
                const requirements =
                    Array.isArray(
                        row.personnelTrainingRequirements
                    )
                        ? row.personnelTrainingRequirements
                        : [];

                const signature =
                    getTrainedPersonnelRequirementsSignature(
                        requirements
                    );

                if (!signature) return;

                const key =
                    `trained-personnel:${signature}`;

                const amount =
                    getTrainedPersonnelVehicleTarget(
                        requirements
                    );

                const existing =
                    merged.get(key);

                if (
                    !existing ||
                    amount >
                        existing.stillNeeded
                ) {
                    merged.set(
                        key,
                        {
                            ...row,
                            stillNeeded:
                                amount,
                            personnelTrainingRequirements:
                                requirements
                        }
                    );
                }

                return;
            }

            if (
                isPublicOrderPersonnelRequirementName(
                    row?.unitName
                )
            ) {
                if (
                    mfDebugEnabled
                ) {
                    debugLog(
                        'PUBLIC ORDER VEHICLE GUARD',
                        `${row.unitName} rejected from the normal vehicle path.`
                    );
                }

                return;
            }

            const mappedName =
                resolveUnitName(
                    row.unitName
                );

            const amount =
                normaliseVehicleRequirementCount(
                    row.unitName,
                    mappedName,
                    row?.stillNeeded
                );

            if (amount <= 0) {
                return;
            }

            const key =
                normaliseVehicleText(
                    mappedName ||
                    row.unitName
                );

            if (!key) return;

            const existing =
                merged.get(
                    key
                );

            if (
                !existing ||
                amount >
                existing.stillNeeded
            ) {
                merged.set(
                    key,
                    {
                        unitName:
                            row.unitName,
                        stillNeeded:
                            amount
                    }
                );
            } else if (mfDebugEnabled) {
                debugLog(
                    'LIVE DEDUPE',
                    `${row.unitName} -> ${mappedName} x${amount} ignored; existing mapped requirement x${existing.stillNeeded}`
                );
            }
        });

        return Array.from(
            merged.values()
        );
    }

    async function readLiveMissionRequirements() {
        if (!isCurrentMissionExecutionOwner('attachment requirement read')) {
            return [];
        }

        synchroniseMissionInstanceState('Unit Finder attachment read');

        const missionKeyAtFetchStart =
            getLocalMissionInstanceKey();

        const url = getMissionHelpUrl();

        if (!url) {
            updateStatusBox('Mission help link not found. Falling back to old vehicle list.');
            return [];
        }

        try {
            updateStatusBox(
                'Reading the mission-help attachment: Vehicle and Personnel Requirements...'
            );

            if (
                mfDebugEnabled
            ) {
                debugLog(
                    'UNIT FINDER ATTACHMENT FETCH',
                    url
                );
            }
            const response = await fetch(url, { credentials: 'include', cache: 'no-store' });

            if (!response.ok) {
                throw new Error(`${response.status} ${response.statusText}`);
            }

            const html = await response.text();

            if (
                missionKeyAtFetchStart !==
                getLocalMissionInstanceKey()
            ) {
                updateStatusBox(
                    'Mission changed while requirements were loading. Old attachment ignored.'
                );
                return [];
            }

            const rows = extractLiveMissionRequirementRows(html);

            if (
                mfDebugEnabled
            ) {
                debugLog(
                    'UNIT FINDER ATTACHMENT RESULT',
                    `${rows.length} merged Vehicle and Personnel Requirements row(s)`
                );
            }

            if (
                rows.length >
                0
            ) {
                updateStatusBox(
                    `Mission-help attachment loaded: ${rows.length} Vehicle and Personnel Requirements row(s).`
                );
            }

            return rows;
        } catch (error) {
            console.warn('Mission Finder V9 live requirement fetch failed:', error);
            updateStatusBox('Live requirements failed. Falling back to old vehicle list.');
            return [];
        }
    }

    function getCurrentStaffingMissionKey() {
        const missionId =
            getCurrentMissionIdForQueueRestart();

        return missionId ||
            getMissionUpdateFirstPassKey() ||
            getCurrentMissionName();
    }

    function resetStaffingBlockForCurrentMission(reason) {
        const missionKey =
            getCurrentStaffingMissionKey();

        if (
            missionKey &&
            missionKey === mfStaffingBlockMissionKey
        ) {
            return;
        }

        mfStaffingBlockMissionKey = missionKey;
        mfStaffingBlockActive = false;
        mfStaffingBlockText = '';

        if (mfDebugEnabled) {
            debugLog(
                'STAFFING GUARD',
                `Reset | reason=${reason || 'mission changed'} | mission=${missionKey || 'unknown'}`
            );
        }
    }


    function readPersonnelTrainingRegistry() {
        try {
            const parsed = JSON.parse(
                localStorage.getItem(
                    MF_PERSONNEL_TRAINING_REGISTRY_KEY
                ) ||
                'null'
            );

            if (
                !parsed ||
                typeof parsed !== 'object' ||
                typeof parsed.vehicles !== 'object'
            ) {
                return {
                    updatedAt:
                        0,
                    vehicles:
                        {}
                };
            }

            return parsed;
        } catch (_error) {
            return {
                updatedAt:
                    0,
                vehicles:
                    {}
            };
        }
    }

    function getMissionVehicleId(
        input
    ) {
        if (!input) return '';

        const row =
            input.closest &&
            input.closest(
                'tr[vehicle_id], tr[data-vehicle-id], tr.vehicle_select_table_tr'
            );

        const idMatches = [
            String(input.id || '').match(/(?:vehicle_checkbox_|vehicle_)(\d+)/i)?.[1],
            String(row?.id || '').match(/(?:vehicle_|vehicle_row_)(\d+)/i)?.[1],
            input.getAttribute('vehicle_id'),
            input.getAttribute('data-vehicle-id'),
            row?.getAttribute('vehicle_id'),
            row?.getAttribute('data-vehicle-id'),
            input.value
        ]
            .map(value => String(value || '').trim())
            .filter(value => /^\d+$/.test(value));

        // Real MissionChief vehicle IDs are long numeric identifiers. Reject
        // short values such as the vehicle type ID "8" rather than matching a
        // registry entry for the wrong vehicle.
        return idMatches.find(value => value.length >= 4) || '';
    }



    function getPublicOrderPersonnelLevel(
        value
    ) {
        const cleaned =
            String(
                value ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        if (
            /^(?:Required\s+)?(?:Level\s*1\s+Public\s+Order|Public\s+Order\s+Level\s*1)\s+Officer(?:s)?$/i
                .test(
                    cleaned
                )
        ) {
            return 1;
        }

        if (
            /^(?:Required\s+)?(?:Level\s*2\s+Public\s+Order|Public\s+Order\s+Level\s*2)\s+Officer(?:s)?$/i
                .test(
                    cleaned
                )
        ) {
            return 2;
        }

        return 0;
    }

    function isPublicOrderPersonnelRequirementName(
        value
    ) {
        return (
            getPublicOrderPersonnelLevel(
                value
            ) >
            0
        );
    }

    function isPoliceSergeantPersonnelRequirementName(
        value
    ) {
        const cleaned =
            String(
                value ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        return /^(?:Required\s+)?Police\s+Sergeant(?:s)?$/i
            .test(
                cleaned
            );
    }

    function isPoliceInspectorPersonnelRequirementName(
        value
    ) {
        const cleaned =
            String(
                value ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        return /^(?:Required\s+)?Police\s+Inspector(?:s)?$/i
            .test(
                cleaned
            );
    }


    function isPoliceMedicPersonnelRequirementName(
        value
    ) {
        const cleaned =
            String(
                value ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        return /^(?:Required\s+)?Police\s+Medic(?:s)?$/i
            .test(
                cleaned
            );
    }

    function isRailwayPolicePersonnelRequirementName(
        value
    ) {
        const cleaned =
            String(
                value ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        return /^(?:Required\s+)?Railway\s+Police\s+Officer(?:s)?$/i
            .test(
                cleaned
            );
    }


    function isArmedResponsePersonnelRequirementName(value) {
        const cleaned = String(value || '')
            .replace(/\s+/g, ' ')
            .trim();

        return /^(?:Required\s+)?Armed(?:\s+Response)?\s+Personnel(?:\s*\(\s*In\s+Armed\s+Vehicles\s*\))?$/i
            .test(cleaned);
    }

    function getArmedResponsePersonnelRequirements(
        requirementName,
        personnelAmount
    ) {
        if (
            !isArmedResponsePersonnelRequirementName(
                requirementName
            )
        ) {
            return [];
        }

        const amountMatch = String(
            personnelAmount ?? ''
        )
            .replace(/,/g, '')
            .match(/\d+/);

        const personnelRequired = amountMatch
            ? Math.max(
                0,
                parseInt(
                    amountMatch[0],
                    10
                ) || 0
            )
            : 0;

        if (personnelRequired <= 0) {
            return [];
        }

        return normalisePublicOrderTrainedRequirements([
            {
                code:
                    'armed_response_personnel',
                label:
                    'Armed Response Personnel',
                required:
                    personnelRequired
            }
        ]);
    }

    function getSupportedTrainedPersonnelRequirementsFromText(
        text
    ) {
        const input =
            String(
                text ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        if (
            !input ||
            !/Missing\s+Personnel:/i.test(
                input
            )
        ) {
            return [];
        }

        const requirements =
            new Map();

        MF_TRAINED_PERSONNEL_PATTERNS
            .forEach(definition => {
                let maximumRequired = 0;

                definition.patterns
                    .forEach(pattern => {
                        pattern.lastIndex = 0;

                        let match;

                        while (
                            (
                                match =
                                    pattern.exec(
                                        input
                                    )
                            )
                        ) {
                            const required =
                                Math.max(
                                    0,
                                    parseInt(
                                        match[1],
                                        10
                                    ) || 0
                                );

                            maximumRequired =
                                Math.max(
                                    maximumRequired,
                                    required
                                );
                        }
                    });

                if (
                    maximumRequired > 0
                ) {
                    requirements.set(
                        definition.code,
                        {
                            code:
                                definition.code,
                            label:
                                definition.label,
                            required:
                                maximumRequired
                        }
                    );
                }
            });

        return normalisePublicOrderTrainedRequirements(
            Array.from(
                requirements.values()
            )
        );
    }

    function normalisePublicOrderTrainedRequirements(
        requirements
    ) {
        const source =
            Array.isArray(requirements)
                ? requirements
                : [];

        const findRequired = code => {
            const item = source.find(
                requirement => requirement.code === code
            );

            return Math.max(
                0,
                parseInt(item?.required, 10) || 0
            );
        };

        const level1Required =
            findRequired('level_1_public_order');

        const level2Required =
            findRequired('level_2_public_order');

        const policeSergeantRequired =
            findRequired('police_sergeant');

        const policeInspectorRequired =
            findRequired('police_inspector');

        const policeMedicRequired =
            findRequired('police_medic');

        const railwayPoliceRequired =
            findRequired('railway_police');

        const armedResponseRequired =
            findRequired('armed_response_personnel');

        const normalised =
            source.filter(requirement => {
                return (
                    requirement.code !==
                        'level_1_public_order' &&
                    requirement.code !==
                        'level_2_public_order' &&
                    requirement.code !==
                        'police_sergeant' &&
                    requirement.code !==
                        'police_inspector' &&
                    requirement.code !==
                        'police_medic' &&
                    requirement.code !==
                        'railway_police' &&
                    requirement.code !==
                        'armed_response_personnel'
                );
            });

        const addStrictTrainedIrvRequirement =
            (
                code,
                label,
                personnelRequired
            ) => {
                if (personnelRequired <= 0) {
                    return;
                }

                const requiredVehicles =
                    Math.ceil(
                        personnelRequired /
                        2
                    );

                normalised.push({
                    code:
                        `${code}_vehicle`,
                    label:
                        `${label} Trained Police IRV`,
                    requirementType:
                        'police_trained_irv_vehicle',
                    required:
                        requiredVehicles,
                    personnelRequired,
                    personnelPerVehicle:
                        2,
                    requiredTrainingCodes: [
                        code
                    ],
                    eligibleVehicleTypeIds: [
                        '8'
                    ]
                });
            };

        // Public Order levels and Sergeant are independent mission profiles.
        // Prefer exact IRVs carrying two personnel with the requested profile,
        // then allow one-person trained IRVs as a fallback until the complete
        // personnel demand is covered. Unrelated profiles are never prerequisites.
        addStrictTrainedIrvRequirement(
            'level_1_public_order',
            'Level 1 Public Order',
            level1Required
        );

        addStrictTrainedIrvRequirement(
            'level_2_public_order',
            'Level 2 Public Order',
            level2Required
        );

        addStrictTrainedIrvRequirement(
            'police_sergeant',
            'Police Sergeant',
            policeSergeantRequired
        );

        if (
            policeInspectorRequired > 0
        ) {
            const requiredInspectorVehicles =
                Math.ceil(
                    policeInspectorRequired /
                    2
                );

            normalised.push({
                code:
                    'police_inspector_vehicle',
                label:
                    'Police Inspector Trained Police IRV',
                requirementType:
                    'police_inspector_vehicle',
                required:
                    requiredInspectorVehicles,
                inspectorsRequired:
                    policeInspectorRequired,
                personnelPerVehicle:
                    2,
                requiredTrainingCodes: [
                    'police_inspector'
                ],
                eligibleVehicleTypeIds: [
                    '8'
                ]
            });
        }

        addStrictTrainedIrvRequirement(
            'police_medic',
            'Police Medic',
            policeMedicRequired
        );

        addStrictTrainedIrvRequirement(
            'railway_police',
            'Railway Police Officer',
            railwayPoliceRequired
        );

        if (armedResponseRequired > 0) {
            const requiredArmedTrafficCars = Math.ceil(
                armedResponseRequired / 2
            );

            normalised.push({
                code: 'armed_response_atc_vehicle',
                label: 'Armed Response Personnel in Armed Traffic Cars',
                requirementType: 'armed_response_atc_vehicle',
                required: requiredArmedTrafficCars,
                personnelRequired: armedResponseRequired,
                personnelPerVehicle: 2,
                requiredTrainingCodes: [
                    'traffic_police',
                    'swat'
                ],
                eligibleVehicleTypeIds: [
                    '25'
                ]
            });
        }

        return normalised;
    }

    function isStrictLiveVerifiedTrainingEntry(
        registryEntry
    ) {
        if (!registryEntry) return false;

        const source =
            String(registryEntry.source || '');

        const updatedAt =
            Number(registryEntry.updatedAt || 0);

        return (
            source.startsWith(
                MF_STRICT_TRAINING_SOURCE_PREFIX
            ) &&
            updatedAt > 0 &&
            Date.now() - updatedAt <=
                MF_LIVE_TRAINING_VERIFY_CACHE_MS
        );
    }


    function isAuthoritativeLivePoliceTrainingEntry(
        registryEntry
    ) {
        return !!(
            isStrictLiveVerifiedTrainingEntry(
                registryEntry
            ) &&
            registryEntry
                .assignmentScanComplete ===
                true
        );
    }


    function getProtectedOrdinaryIrvTrainingCount(
        registryEntry
    ) {
        if (!registryEntry) return 0;

        const trainingCounts =
            registryEntry.trainingCounts &&
            typeof registryEntry.trainingCounts === 'object'
                ? registryEntry.trainingCounts
                : {};

        return MF_PROTECTED_ORDINARY_IRV_TRAINING_CODES
            .reduce((total, code) => {
                return total + Math.max(
                    0,
                    parseInt(trainingCounts[code], 10) || 0
                );
            }, 0);
    }

    function isKnownProtectedTrainedPoliceIrvEntry(
        registryEntry
    ) {
        if (!registryEntry) return false;

        const vehicleTypeId =
            String(registryEntry.vehicleTypeId || '');

        // Exact MissionChief vehicle IDs are authoritative here. Older shared
        // registry records may pre-date vehicle-type capture, so a missing type
        // must not weaken a positive specialist-training signal.
        return !!(
            (!vehicleTypeId || vehicleTypeId === '8') &&
            getProtectedOrdinaryIrvTrainingCount(
                registryEntry
            ) > 0
        );
    }

    function isVerifiedOrdinaryPoliceIrvEntry(
        registryEntry
    ) {
        if (!registryEntry) return false;

        const vehicleTypeId =
            String(registryEntry.vehicleTypeId || '');

        return !!(
            (!vehicleTypeId || vehicleTypeId === '8') &&
            isAuthoritativeLivePoliceTrainingEntry(registryEntry) &&
            getProtectedOrdinaryIrvTrainingCount(
                registryEntry
            ) === 0
        );
    }

    function isOrdinaryPoliceIrvCheckboxEligible(
        checkbox,
        registry,
        options = {}
    ) {
        if (!isPoliceCarVehicleCheckbox(checkbox)) {
            return false;
        }

        const allowUnknown =
            options.allowUnknown === true;

        const registryMatch =
            getRegistryEntryForMissionCheckbox(
                checkbox,
                registry
            );

        if (!registryMatch.entry) {
            return allowUnknown;
        }

        // A known specialist crew is always protected, even when the registry
        // entry is older than the live-verification cache window.
        if (
            isKnownProtectedTrainedPoliceIrvEntry(
                registryMatch.entry
            )
        ) {
            return false;
        }

        if (
            isVerifiedOrdinaryPoliceIrvEntry(
                registryMatch.entry
            )
        ) {
            return true;
        }

        return allowUnknown;
    }

    function orderOrdinaryPoliceIrvCandidates(
        candidates,
        registry
    ) {
        const verifiedOrdinary = [];
        const unknownOrStale = [];

        (Array.isArray(candidates) ? candidates : [])
            .forEach(checkbox => {
                const registryMatch =
                    getRegistryEntryForMissionCheckbox(
                        checkbox,
                        registry
                    );

                if (
                    isKnownProtectedTrainedPoliceIrvEntry(
                        registryMatch.entry
                    )
                ) {
                    return;
                }

                if (
                    isVerifiedOrdinaryPoliceIrvEntry(
                        registryMatch.entry
                    )
                ) {
                    verifiedOrdinary.push(checkbox);
                    return;
                }

                unknownOrStale.push(checkbox);
            });

        return [
            ...verifiedOrdinary,
            ...unknownOrStale
        ];
    }


    function getMissionTrainingCombinationKey(trainingCodes) {
        return Array.from(
            new Set(
                (Array.isArray(trainingCodes) ? trainingCodes : [])
                    .map(String)
                    .filter(Boolean)
            )
        )
            .sort()
            .join('+');
    }

    function getTrainingRequirementPersonnelTarget(requirement) {
        if (!requirement) return 0;

        const explicitPersonnelTargets = [
            requirement.personnelRequired,
            requirement.inspectorsRequired
        ]
            .map(value => Math.max(0, parseInt(value, 10) || 0))
            .filter(value => value > 0);

        if (explicitPersonnelTargets.length > 0) {
            return Math.max(...explicitPersonnelTargets);
        }

        const requiredVehicles =
            Math.max(0, parseInt(requirement.required, 10) || 0);

        if (
            requirement.requirementType === 'armed_response_atc_vehicle' ||
            requirement.requirementType === 'police_inspector_vehicle' ||
            requirement.requirementType === 'police_trained_irv_vehicle'
        ) {
            const personnelPerVehicle =
                Math.max(
                    1,
                    parseInt(requirement.personnelPerVehicle, 10) || 2
                );

            return requiredVehicles * personnelPerVehicle;
        }

        return requiredVehicles;
    }

    function getStrictTrainingVehicleContribution(
        requirement,
        qualifiedCount
    ) {
        const personnelPerVehicle =
            Math.max(
                1,
                parseInt(requirement?.personnelPerVehicle, 10) || 2
            );

        return Math.min(
            personnelPerVehicle,
            Math.max(0, parseInt(qualifiedCount, 10) || 0)
        );
    }

    function getTrainingRequirementContribution(
        requirement,
        registryEntry
    ) {
        if (
            !requirement ||
            !registryEntry
        ) {
            return 0;
        }

        const trainingCounts =
            registryEntry.trainingCounts &&
            typeof registryEntry.trainingCounts ===
                'object'
                ? registryEntry.trainingCounts
                : {};

        const trainingCombinationCounts =
            registryEntry.trainingCombinationCounts &&
            typeof registryEntry.trainingCombinationCounts === 'object'
                ? registryEntry.trainingCombinationCounts
                : {};

        const allowedTypes =
            new Set(
                (
                    requirement
                        .eligibleVehicleTypeIds ||
                    []
                ).map(String)
            );

        if (
            allowedTypes.size > 0 &&
            !allowedTypes.has(
                String(
                    registryEntry.vehicleTypeId ||
                    ''
                )
            )
        ) {
            return 0;
        }

        if (
            requirement.requirementType ===
                'armed_response_atc_vehicle'
        ) {
            if (
                !isAuthoritativeLivePoliceTrainingEntry(
                    registryEntry
                )
            ) {
                return 0;
            }

            const combinationKey =
                getMissionTrainingCombinationKey(
                    requirement.requiredTrainingCodes
                );

            const qualifiedDualTrainedCount =
                parseInt(
                    trainingCombinationCounts[combinationKey],
                    10
                ) || 0;

            return getStrictTrainingVehicleContribution(
                requirement,
                qualifiedDualTrainedCount
            );
        }

        if (
            requirement.requirementType ===
                'police_inspector_vehicle'
        ) {
            if (
                !isAuthoritativeLivePoliceTrainingEntry(
                    registryEntry
                )
            ) {
                return 0;
            }

            return getStrictTrainingVehicleContribution(
                requirement,
                trainingCounts.police_inspector
            );
        }

        if (
            requirement.requirementType ===
                'police_trained_irv_vehicle'
        ) {
            if (
                !isAuthoritativeLivePoliceTrainingEntry(
                    registryEntry
                )
            ) {
                return 0;
            }

            const requiredCodes =
                Array.isArray(
                    requirement.requiredTrainingCodes
                )
                    ? requirement.requiredTrainingCodes
                    : [];

            if (requiredCodes.length !== 1) {
                return 0;
            }

            return getStrictTrainingVehicleContribution(
                requirement,
                trainingCounts[requiredCodes[0]]
            );
        }

        return (
            parseInt(
                trainingCounts[
                    requirement.code
                ],
                10
            ) || 0
        );
    }

    function getTrainedPersonnelVehicleTarget(
        requirements
    ) {
        const targets =
            (
                Array.isArray(requirements)
                    ? requirements
                    : []
            )
                .map(requirement => {
                    return Math.max(
                        0,
                        parseInt(
                            requirement?.required,
                            10
                        ) || 0
                    );
                })
                .filter(
                    target =>
                        target > 0
                );

        return targets.length
            ? Math.max(...targets)
            : 1;
    }

    function mergeTrainedPersonnelRequirements(
        target,
        requirements
    ) {
        (
            Array.isArray(requirements)
                ? requirements
                : []
        ).forEach(requirement => {
            const code =
                String(
                    requirement?.code ||
                    ''
                );

            const required =
                Math.max(
                    0,
                    parseInt(
                        requirement?.required,
                        10
                    ) || 0
                );

            if (
                !code ||
                required <= 0
            ) {
                return;
            }

            const existing =
                target.get(code);

            if (
                !existing ||
                required >
                    existing.required
            ) {
                target.set(
                    code,
                    {
                        ...requirement,
                        code,
                        label:
                            String(
                                requirement?.label ||
                                code
                            ),
                        required
                    }
                );
            }
        });
    }

    function getTrainedPersonnelRequirementsSignature(
        requirements
    ) {
        return (
            Array.isArray(requirements)
                ? requirements
                : []
        )
            .map(requirement => {
                return [
                    String(
                        requirement?.code ||
                        ''
                    ),
                    Math.max(
                        0,
                        parseInt(
                            requirement?.required,
                            10
                        ) || 0
                    )
                ].join(':');
            })
            .filter(Boolean)
            .sort()
            .join(',');
    }

    function formatTrainedPersonnelRequirements(
        requirements
    ) {
        return (
            Array.isArray(requirements)
                ? requirements
                : []
        )
            .map(requirement => {

                if (
                    requirement.requirementType ===
                    'armed_response_atc_vehicle'
                ) {
                    return (
                        `${requirement.label} x${requirement.required} ` +
                        `(${requirement.personnelRequired} required; ` +
                        `prefer 2 personnel who each hold Roads Policing + Firearms per exact type-25 ATC; fallback accepts 1 until the full personnel demand is covered)`
                    );
                }

                if (
                    requirement
                        .requirementType ===
                    'police_inspector_vehicle'
                ) {
                    return (
                        `${requirement.label} x${requirement.required} ` +
                        `(${requirement.inspectorsRequired} Inspector` +
                        `${requirement.inspectorsRequired === 1 ? '' : 's'}; ` +
                        `prefer 2 Inspector-trained personnel per exact IRV; fallback accepts 1 until the full Inspector demand is covered)`
                    );
                }


                if (
                    requirement
                        .requirementType ===
                    'police_trained_irv_vehicle'
                ) {
                    return (
                        `${requirement.label} x${requirement.required} ` +
                        `(${requirement.personnelRequired} required; ` +
                        `prefer 2 ${requirement.requiredTrainingCodes?.[0] || 'trained'} personnel per exact IRV; fallback accepts 1 until the full personnel demand is covered)`
                    );
                }

                return `${requirement.label} x${requirement.required}`;
            })
            .join(', ');
    }


    function hasPoliceInspectorVehicleRequirement(requirements) {
        return (
            Array.isArray(requirements)
                ? requirements
                : []
        ).some(requirement => {
            return (
                requirement?.requirementType ===
                    'police_inspector_vehicle' ||
                requirement?.code ===
                    'police_inspector_vehicle'
            );
        });
    }

    function getNormalisedRegistryVehicleName(value) {
        return String(value || '')
            .replace(/&amp;/gi, '&')
            .replace(/[^a-z0-9]+/gi, ' ')
            .replace(/\s+/g, ' ')
            .trim()
            .toLowerCase();
    }

    function hasStrictPoliceTrainingRequirement(
        requirements
    ) {
        return (
            Array.isArray(requirements)
                ? requirements
                : []
        ).some(requirement => {
            return (
                requirement?.requirementType ===
                    'police_inspector_vehicle' ||
                requirement?.requirementType ===
                    'police_trained_irv_vehicle'
            );
        });
    }

    function getRegistryEntryForMissionCheckbox(
        checkbox,
        registry
    ) {
        const vehicleId =
            getMissionVehicleId(checkbox);

        if (!vehicleId) {
            return {
                vehicleId: '',
                entry: null,
                matchMode: 'no-exact-vehicle-id'
            };
        }

        const directEntry =
            registry?.vehicles?.[vehicleId];

        if (!directEntry) {
            return {
                vehicleId,
                entry: null,
                matchMode: 'none'
            };
        }

        const checkboxTypeIds =
            new Set(
                getVehicleTypeIdentifiers(
                    checkbox
                ).map(String)
            );

        const entryTypeId =
            String(
                directEntry.vehicleTypeId ||
                ''
            );

        if (
            entryTypeId &&
            checkboxTypeIds.size > 0 &&
            !checkboxTypeIds.has(entryTypeId)
        ) {
            return {
                vehicleId,
                entry: null,
                matchMode: 'vehicle-type-mismatch'
            };
        }

        return {
            vehicleId,
            entry: directEntry,
            matchMode: 'exact-vehicle-id'
        };
    }


    function parseVehicleIdFromAssignmentLink(value) {
        const match = String(value || '')
            .match(/\/vehicles\/(\d+)(?:\/|$|[?#])/i);

        return match
            ? String(match[1])
            : '';
    }

    function parseLivePoliceTrainingAssignments(
        html,
        currentVehicleId
    ) {
        const doc = new DOMParser()
            .parseFromString(
                String(html || ''),
                'text/html'
            );

        const currentId =
            String(currentVehicleId || '');

        const supportedCodes =
            new Set(
                MF_PROTECTED_ORDINARY_IRV_TRAINING_CODES
            );

        const trainingCounts = {};
        const trainingCombinationCounts = {};
        let assignedPersonnelCount = 0;

        const personnelTable =
            doc.querySelector(
                '#personal_table'
            );

        const personnelRows =
            personnelTable
                ? Array.from(
                    personnelTable.querySelectorAll(
                        'tbody tr[data-filterable-by], tbody tr'
                    )
                )
                : [];

        const detectedVehicleTypeId =
            String(
                doc.querySelector(
                    '.vehicle_image_reload[vehicle_type_id]'
                )?.getAttribute('vehicle_type_id') ||
                ''
            );

        personnelRows.forEach(row => {
            const assignmentActions =
                Array.from(
                    row.querySelectorAll(
                        'a[href*="/zuweisungDo/"], button, input[type="submit"], input[type="button"]'
                    )
                );

            const assignedAction =
                assignmentActions.find(action => {
                    const actionText =
                        String(
                            action?.innerText ||
                            action?.textContent ||
                            action?.value ||
                            ''
                        )
                            .replace(/\s+/g, ' ')
                            .trim();

                    return !!(
                        action?.classList?.contains(
                            'btn-assigned'
                        ) ||
                        /remove\s+binding/i.test(
                            actionText
                        )
                    );
                }) || null;

            const assignedText =
                String(
                    assignedAction?.innerText ||
                    assignedAction?.textContent ||
                    assignedAction?.value ||
                    ''
                )
                    .replace(/\s+/g, ' ')
                    .trim();

            const assignedHere = !!(
                assignedAction &&
                (
                    assignedAction.classList?.contains(
                        'btn-assigned'
                    ) ||
                    /remove\s+binding/i.test(
                        assignedText
                    )
                )
            );

            if (!assignedHere) return;

            // On /vehicles/{id}/zuweisung a btn-assigned row belongs to the
            // current vehicle. Do not infer ownership from the displayed name.
            const actionVehicleId =
                parseVehicleIdFromAssignmentLink(
                    assignedAction.getAttribute('href') ||
                    assignedAction.href ||
                    ''
                );

            if (
                currentId &&
                actionVehicleId &&
                actionVehicleId !== currentId
            ) {
                return;
            }

            assignedPersonnelCount += 1;

            const filterText = String(
                row.getAttribute('data-filterable-by') ||
                ''
            );

            const rowText = String(
                row.innerText ||
                row.textContent ||
                ''
            )
                .replace(/\s+/g, ' ')
                .trim();

            const rowCodes = new Set(
                (
                    filterText.match(
                        /[a-z][a-z0-9_]+/gi
                    ) ||
                    []
                )
                    .map(code => code.toLowerCase())
                    .filter(code => supportedCodes.has(code))
            );

            if (/Level\s*1\s+Public\s+Order/i.test(rowText)) {
                rowCodes.add('level_1_public_order');
            }

            if (/Level\s*2\s+Public\s+Order/i.test(rowText)) {
                rowCodes.add('level_2_public_order');
            }

            if (/\bPolice\s+Sergeant\b/i.test(rowText)) {
                rowCodes.add('police_sergeant');
            }

            if (/\bPolice\s+Medic\b/i.test(rowText)) {
                rowCodes.add('police_medic');
            }

            if (/\bPolice\s+Inspector\b/i.test(rowText)) {
                rowCodes.add('police_inspector');
            }

            if (
                /\bRailway\s+Police\s+Officer\b/i.test(
                    rowText
                ) ||
                /\bRailway\s+Policing\b/i.test(
                    rowText
                )
            ) {
                rowCodes.add('railway_police');
            }

            rowCodes.forEach(code => {
                trainingCounts[code] =
                    Number(
                        trainingCounts[code] ||
                        0
                    ) + 1;
            });

            const roadsFirearmsKey =
                getMissionTrainingCombinationKey([
                    'traffic_police',
                    'swat'
                ]);

            if (
                rowCodes.has('traffic_police') &&
                rowCodes.has('swat')
            ) {
                trainingCombinationCounts[roadsFirearmsKey] =
                    Number(
                        trainingCombinationCounts[roadsFirearmsKey] ||
                        0
                    ) + 1;
            }
        });

        supportedCodes.forEach(code => {
            if (
                !Object.prototype.hasOwnProperty.call(
                    trainingCounts,
                    code
                )
            ) {
                trainingCounts[code] = 0;
            }
        });

        return {
            vehicleId: currentId,
            trainingCounts,
            trainingCombinationCounts,
            assignedPersonnelCount,
            assignmentScanComplete:
                Boolean(personnelTable),
            personnelRowsSeen:
                personnelRows.length,
            detectedVehicleTypeId,
            document: doc
        };
    }


    // Compatibility wrapper retained for older guarded call paths. The strict
    // parser now returns exact current-vehicle counts for all supported Police
    // training codes, including Police Inspector.
    function parseLivePoliceInspectorAssignments(
        html,
        currentVehicleId
    ) {
        const parsed =
            parseLivePoliceTrainingAssignments(
                html,
                currentVehicleId
            );

        return {
            countsByVehicleId: {
                [String(currentVehicleId || '')]:
                    Number(
                        parsed.trainingCounts
                            ?.police_inspector ||
                        0
                    )
            },
            detectedVehicleTypeId:
                parsed.detectedVehicleTypeId,
            document:
                parsed.document
        };
    }

    function savePersonnelTrainingRegistry(registry) {
        if (!registry || typeof registry !== 'object') {
            return false;
        }

        try {
            registry.updatedAt = Date.now();
            localStorage.setItem(
                MF_PERSONNEL_TRAINING_REGISTRY_KEY,
                JSON.stringify(registry)
            );
            return true;
        } catch (_error) {
            return false;
        }
    }

    function getUnverifiedRegistryTrainingHintScore(
        requirements,
        registryEntry
    ) {
        if (!registryEntry) return 0;

        const trainingCounts =
            registryEntry.trainingCounts &&
            typeof registryEntry.trainingCounts === 'object'
                ? registryEntry.trainingCounts
                : {};

        const trainingCombinationCounts =
            registryEntry.trainingCombinationCounts &&
            typeof registryEntry.trainingCombinationCounts === 'object'
                ? registryEntry.trainingCombinationCounts
                : {};

        const entryTypeId =
            String(
                registryEntry.vehicleTypeId ||
                ''
            );

        const getPreferenceScore = qualifiedCount => {
            const count =
                Math.max(0, parseInt(qualifiedCount, 10) || 0);

            if (count >= 2) {
                return 2000 + Math.min(count, 2);
            }

            return count === 1
                ? 1001
                : 0;
        };

        return (
            Array.isArray(requirements)
                ? requirements
                : []
        ).reduce((score, requirement) => {
            const allowedTypes =
                new Set(
                    (
                        requirement?.eligibleVehicleTypeIds ||
                        []
                    ).map(String)
                );

            if (
                allowedTypes.size > 0 &&
                !allowedTypes.has(entryTypeId)
            ) {
                return score;
            }

            if (
                requirement?.requirementType ===
                    'armed_response_atc_vehicle'
            ) {
                const combinationKey =
                    getMissionTrainingCombinationKey(
                        requirement.requiredTrainingCodes
                    );

                return score + getPreferenceScore(
                    trainingCombinationCounts[combinationKey]
                );
            }

            if (
                requirement?.requirementType ===
                    'police_inspector_vehicle'
            ) {
                return score + getPreferenceScore(
                    trainingCounts.police_inspector
                );
            }

            if (
                requirement?.requirementType ===
                    'police_trained_irv_vehicle'
            ) {
                const requiredCodes =
                    Array.isArray(
                        requirement.requiredTrainingCodes
                    )
                        ? requirement.requiredTrainingCodes
                        : [];

                if (requiredCodes.length === 1) {
                    return score + getPreferenceScore(
                        trainingCounts[requiredCodes[0]]
                    );
                }
            }

            return score;
        }, 0);
    }

    function orderStrictPoliceTrainingCandidates(
        candidates,
        requirements,
        registry
    ) {
        const source =
            Array.isArray(candidates)
                ? candidates
                : [];

        const arrivalIndex =
            new Map(
                source.map((checkbox, index) => [
                    checkbox,
                    index
                ])
            );

        const checked =
            source.filter(checkbox => checkbox.checked);

        const unchecked =
            source.filter(checkbox => !checkbox.checked);

        const hinted =
            unchecked
                .map(checkbox => {
                    const registryMatch =
                        getRegistryEntryForMissionCheckbox(
                            checkbox,
                            registry
                        );

                    return {
                        checkbox,
                        score:
                            getUnverifiedRegistryTrainingHintScore(
                                requirements,
                                registryMatch.entry
                            )
                    };
                })
                .filter(item => item.score > 0)
                .sort((left, right) => {
                    if (left.score !== right.score) {
                        return right.score - left.score;
                    }

                    return (
                        arrivalIndex.get(left.checkbox) -
                        arrivalIndex.get(right.checkbox)
                    );
                })
                .map(item => item.checkbox);

        const hintedSet = new Set(hinted);

        const remaining =
            unchecked.filter(
                checkbox => !hintedSet.has(checkbox)
            );

        return [
            ...checked,
            ...hinted,
            ...remaining
        ].filter((checkbox, index, array) => {
            return array.indexOf(checkbox) === index;
        });
    }

    async function refreshPoliceInspectorRegistryFromLiveVehicles(
        requirements,
        source = 'UPDATE'
    ) {
        if (
            !hasStrictPoliceTrainingRequirement(
                requirements
            )
        ) {
            return {
                refreshed: false,
                pagesRead: 0,
                qualifyingVehicles: 0
            };
        }

        let registry =
            readPersonnelTrainingRegistry();

        if (!registry.vehicles) {
            registry.vehicles = {};
        }

        const allIrvCandidates =
            sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(checkbox => {
                    return (
                        (!checkbox.disabled || checkbox.checked) &&
                        isPoliceCarVehicleCheckbox(checkbox) &&
                        !!getMissionVehicleId(checkbox)
                    );
                })
            );

        // The Personnel Assignment registry is an exact-ID hint only.
        // It is never trusted as final proof, but it places known Inspector or
        // requested Public Order IRVs at the front of the live verification
        // queue. The exact /vehicles/{id}/zuweisung page is still authoritative.
        const orderedCandidates =
            orderStrictPoliceTrainingCandidates(
                allIrvCandidates,
                requirements,
                registry
            );

        const verifiedIds = new Set();
        const now = Date.now();

        orderedCandidates.forEach(checkbox => {
            const vehicleId =
                getMissionVehicleId(checkbox);

            const entry =
                registry.vehicles?.[vehicleId];

            const cachedAt =
                Number(
                    mfLiveTrainingVerifyCache.get(
                        vehicleId
                    ) ||
                    0
                );

            if (
                vehicleId &&
                isAuthoritativeLivePoliceTrainingEntry(entry) &&
                now - cachedAt <=
                    MF_LIVE_TRAINING_VERIFY_CACHE_MS
            ) {
                verifiedIds.add(vehicleId);
            }
        });

        const requirementsSatisfiedByVerified = () => {
            const verifiedCheckboxes =
                orderedCandidates.filter(checkbox => {
                    return verifiedIds.has(
                        getMissionVehicleId(checkbox)
                    );
                });

            return getRemainingTrainedPersonnelRequirements(
                requirements,
                verifiedCheckboxes,
                registry
            ).every(requirement => {
                return requirement.remaining <= 0;
            });
        };

        if (requirementsSatisfiedByVerified()) {
            return {
                refreshed: false,
                pagesRead: 0,
                qualifyingVehicles:
                    verifiedIds.size
            };
        }

        const unverifiedCandidates =
            orderedCandidates.filter(checkbox => {
                const vehicleId =
                    getMissionVehicleId(checkbox);

                return (
                    vehicleId &&
                    !verifiedIds.has(vehicleId)
                );
            });

        const registryHintedCandidates =
            unverifiedCandidates.filter(checkbox => {
                const registryMatch =
                    getRegistryEntryForMissionCheckbox(
                        checkbox,
                        registry
                    );

                return (
                    getUnverifiedRegistryTrainingHintScore(
                        requirements,
                        registryMatch.entry
                    ) > 0
                );
            });

        const registryHintedSet =
            new Set(registryHintedCandidates);

        const ordinaryCandidates =
            unverifiedCandidates.filter(
                checkbox =>
                    !registryHintedSet.has(checkbox)
            );

        // Always verify the exact registry-hinted IRVs first. Then use the
        // established arrival-sorted cap for ordinary candidates. This fixes
        // trained station vehicles being missed simply because they sit beyond
        // the first 48 normal IRVs in a large mission vehicle list.
        const pagesToRead = [
            ...registryHintedCandidates,
            ...ordinaryCandidates.slice(
                0,
                Math.max(
                    0,
                    MF_LIVE_TRAINING_VERIFY_MAX_PAGES -
                    registryHintedCandidates.length
                )
            )
        ];

        let pagesRead = 0;
        let changed = false;

        for (
            let offset = 0;
            offset < pagesToRead.length;
            offset += MF_LIVE_TRAINING_VERIFY_BATCH_SIZE
        ) {
            const batch = pagesToRead.slice(
                offset,
                offset + MF_LIVE_TRAINING_VERIFY_BATCH_SIZE
            );

            const results = await Promise.all(
                batch.map(async checkbox => {
                    const vehicleId =
                        getMissionVehicleId(checkbox);

                    try {
                        const response = await fetch(
                            `/vehicles/${vehicleId}/zuweisung`,
                            {
                                credentials: 'include',
                                cache: 'no-store',
                                headers: {
                                    Accept: 'text/html,application/xhtml+xml'
                                }
                            }
                        );

                        if (!response.ok) {
                            return null;
                        }

                        const html = await response.text();

                        return {
                            checkbox,
                            vehicleId,
                            parsed:
                                parseLivePoliceTrainingAssignments(
                                    html,
                                    vehicleId
                                )
                        };
                    } catch (_error) {
                        return null;
                    }
                })
            );

            results.filter(result => result?.parsed?.assignmentScanComplete).forEach(result => {
                const {
                    checkbox,
                    vehicleId,
                    parsed
                } = result;

                const existing =
                    registry.vehicles?.[vehicleId] ||
                    {};

                registry.vehicles[vehicleId] = {
                    ...existing,
                    vehicleId,
                    vehicleName:
                        existing.vehicleName ||
                        getVehicleDebugName(checkbox),
                    vehicleTypeId:
                        String(
                            getVehicleTypeIdentifiers(checkbox)[0] ||
                            parsed.detectedVehicleTypeId ||
                            existing.vehicleTypeId ||
                            '8'
                        ),
                    assignedPersonnelCount:
                        parsed.assignedPersonnelCount,
                    assignmentScanComplete:
                        parsed.assignmentScanComplete,
                    personnelRowsSeen:
                        parsed.personnelRowsSeen,
                    trainingCounts: {
                        ...(
                            existing.trainingCounts &&
                            typeof existing.trainingCounts === 'object'
                                ? existing.trainingCounts
                                : {}
                        ),
                        ...parsed.trainingCounts
                    },
                    trainingCombinationCounts: {
                        ...(
                            existing.trainingCombinationCounts &&
                            typeof existing.trainingCombinationCounts === 'object'
                                ? existing.trainingCombinationCounts
                                : {}
                        ),
                        ...parsed.trainingCombinationCounts
                    },
                    updatedAt:
                        Date.now(),
                    source:
                        `${MF_STRICT_TRAINING_SOURCE_PREFIX}${String(source || 'update').toLowerCase()}-v10676`
                };

                mfLiveTrainingVerifyCache.set(
                    vehicleId,
                    Date.now()
                );

                verifiedIds.add(vehicleId);
                pagesRead += 1;
                changed = true;
            });

            if (changed) {
                savePersonnelTrainingRegistry(
                    registry
                );
            }

            if (requirementsSatisfiedByVerified()) {
                break;
            }
        }

        return {
            refreshed: changed,
            pagesRead,
            qualifyingVehicles:
                verifiedIds.size
        };
    }



    async function refreshArmedResponseRegistryFromLiveVehicles(
        requirements,
        source = 'UPDATE'
    ) {
        const armedRequirements = (
            Array.isArray(requirements) ? requirements : []
        ).filter(requirement => {
            return requirement?.requirementType ===
                'armed_response_atc_vehicle';
        });

        if (!armedRequirements.length) {
            return {
                refreshed: false,
                pagesRead: 0,
                qualifyingVehicles: 0
            };
        }

        let registry = readPersonnelTrainingRegistry();
        if (!registry.vehicles) registry.vehicles = {};

        const candidates = sortVehicleCheckboxesByBestArrival(
            getVehicleCheckboxSnapshot().filter(checkbox => {
                return (
                    (!checkbox.disabled || checkbox.checked) &&
                    isArmedTrafficCarVehicleCheckbox(checkbox) &&
                    !!getMissionVehicleId(checkbox)
                );
            })
        );

        const orderedCandidates = orderStrictPoliceTrainingCandidates(
            candidates,
            armedRequirements,
            registry
        );
        const verifiedIds = new Set();
        const now = Date.now();

        orderedCandidates.forEach(checkbox => {
            const vehicleId = getMissionVehicleId(checkbox);
            const entry = registry.vehicles?.[vehicleId];
            const cachedAt = Number(
                mfLiveTrainingVerifyCache.get(vehicleId) || 0
            );

            if (
                vehicleId &&
                String(entry?.vehicleTypeId || '') === '25' &&
                isAuthoritativeLivePoliceTrainingEntry(entry) &&
                now - cachedAt <= MF_LIVE_TRAINING_VERIFY_CACHE_MS
            ) {
                verifiedIds.add(vehicleId);
            }
        });

        const requirementsSatisfiedByVerified = () => {
            const verifiedCheckboxes = orderedCandidates.filter(checkbox => {
                return verifiedIds.has(getMissionVehicleId(checkbox));
            });

            return getRemainingTrainedPersonnelRequirements(
                armedRequirements,
                verifiedCheckboxes,
                registry
            ).every(requirement => requirement.remaining <= 0);
        };

        if (requirementsSatisfiedByVerified()) {
            return {
                refreshed: false,
                pagesRead: 0,
                qualifyingVehicles: verifiedIds.size
            };
        }

        const unverified = orderedCandidates.filter(checkbox => {
            const vehicleId = getMissionVehicleId(checkbox);
            return vehicleId && !verifiedIds.has(vehicleId);
        });

        const hinted = unverified.filter(checkbox => {
            const entry = getRegistryEntryForMissionCheckbox(
                checkbox,
                registry
            ).entry;
            return getUnverifiedRegistryTrainingHintScore(
                armedRequirements,
                entry
            ) > 0;
        });
        const hintedSet = new Set(hinted);
        const pagesToRead = [
            ...hinted,
            ...unverified.filter(checkbox => !hintedSet.has(checkbox))
        ].slice(0, MF_LIVE_TRAINING_VERIFY_MAX_PAGES);

        let pagesRead = 0;
        let changed = false;

        for (
            let offset = 0;
            offset < pagesToRead.length;
            offset += MF_LIVE_TRAINING_VERIFY_BATCH_SIZE
        ) {
            const batch = pagesToRead.slice(
                offset,
                offset + MF_LIVE_TRAINING_VERIFY_BATCH_SIZE
            );

            const results = await Promise.all(
                batch.map(async checkbox => {
                    const vehicleId = getMissionVehicleId(checkbox);
                    try {
                        const response = await fetch(
                            `/vehicles/${vehicleId}/zuweisung`,
                            {
                                credentials: 'include',
                                cache: 'no-store',
                                headers: {
                                    Accept: 'text/html,application/xhtml+xml'
                                }
                            }
                        );
                        if (!response.ok) return null;
                        return {
                            checkbox,
                            vehicleId,
                            parsed: parseLivePoliceTrainingAssignments(
                                await response.text(),
                                vehicleId
                            )
                        };
                    } catch (_error) {
                        return null;
                    }
                })
            );

            results
                .filter(result => result?.parsed?.assignmentScanComplete)
                .forEach(result => {
                    const existing = registry.vehicles?.[result.vehicleId] || {};
                    registry.vehicles[result.vehicleId] = {
                        ...existing,
                        vehicleId: result.vehicleId,
                        vehicleName:
                            existing.vehicleName ||
                            getVehicleDebugName(result.checkbox),
                        vehicleTypeId: '25',
                        assignedPersonnelCount:
                            result.parsed.assignedPersonnelCount,
                        assignmentScanComplete:
                            result.parsed.assignmentScanComplete,
                        personnelRowsSeen:
                            result.parsed.personnelRowsSeen,
                        trainingCounts: {
                            ...(
                                existing.trainingCounts &&
                                typeof existing.trainingCounts === 'object'
                                    ? existing.trainingCounts
                                    : {}
                            ),
                            ...result.parsed.trainingCounts
                        },
                        trainingCombinationCounts: {
                            ...(
                                existing.trainingCombinationCounts &&
                                typeof existing.trainingCombinationCounts === 'object'
                                    ? existing.trainingCombinationCounts
                                    : {}
                            ),
                            ...result.parsed.trainingCombinationCounts
                        },
                        updatedAt: Date.now(),
                        source:
                            `${MF_STRICT_TRAINING_SOURCE_PREFIX}armed-response-${String(source || 'update').toLowerCase()}-v10676`
                    };

                    mfLiveTrainingVerifyCache.set(
                        result.vehicleId,
                        Date.now()
                    );
                    verifiedIds.add(result.vehicleId);
                    pagesRead += 1;
                    changed = true;
                });

            if (changed) savePersonnelTrainingRegistry(registry);
            if (requirementsSatisfiedByVerified()) break;
        }

        return {
            refreshed: changed,
            pagesRead,
            qualifyingVehicles: verifiedIds.size
        };
    }

    function getOrdinaryPoliceVehicleRequirementCount(
        rows
    ) {
        return (Array.isArray(rows) ? rows : [])
            .reduce((total, row) => {
                if (
                    !row ||
                    row.isTrainedPersonnelRequirement
                ) {
                    return total;
                }

                const mappedName =
                    resolveUnitName(row.unitName);

                if (
                    !isPoliceCarRequirement(
                        row.unitName,
                        mappedName
                    )
                ) {
                    return total;
                }

                return total + Math.max(
                    0,
                    parseInt(row.stillNeeded, 10) || 0
                );
            }, 0);
    }

    async function refreshOrdinaryPoliceRegistryFromLiveVehicles(
        rows,
        source = 'UPDATE'
    ) {
        const ordinaryVehiclesRequired =
            getOrdinaryPoliceVehicleRequirementCount(
                rows
            );

        if (ordinaryVehiclesRequired <= 0) {
            return {
                refreshed: false,
                pagesRead: 0,
                verifiedOrdinaryVehicles: 0,
                required: 0
            };
        }

        let registry =
            readPersonnelTrainingRegistry();

        if (!registry.vehicles) {
            registry.vehicles = {};
        }

        const candidates =
            sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(checkbox => {
                    return !!(
                        (!checkbox.disabled || checkbox.checked) &&
                        isPoliceCarVehicleCheckbox(checkbox) &&
                        getMissionVehicleId(checkbox)
                    );
                })
            );

        const selectableCandidates =
            candidates.filter(checkbox => {
                return !checkbox.disabled && !checkbox.checked;
            });

        const countVerifiedOrdinary = () => {
            return selectableCandidates.filter(checkbox => {
                const registryMatch =
                    getRegistryEntryForMissionCheckbox(
                        checkbox,
                        registry
                    );

                return isVerifiedOrdinaryPoliceIrvEntry(
                    registryMatch.entry
                );
            }).length;
        };

        const hasUnverifiedCheckedVehicles = () => {
            return candidates.some(checkbox => {
                if (!checkbox.checked) return false;

                const registryMatch =
                    getRegistryEntryForMissionCheckbox(
                        checkbox,
                        registry
                    );

                return !isAuthoritativeLivePoliceTrainingEntry(
                    registryMatch.entry
                );
            });
        };

        if (
            !hasUnverifiedCheckedVehicles() &&
            countVerifiedOrdinary() >=
            ordinaryVehiclesRequired
        ) {
            return {
                refreshed: false,
                pagesRead: 0,
                verifiedOrdinaryVehicles:
                    countVerifiedOrdinary(),
                required:
                    ordinaryVehiclesRequired
            };
        }

        const now = Date.now();

        const unverified =
            candidates.filter(checkbox => {
                const vehicleId =
                    getMissionVehicleId(checkbox);

                const entry =
                    registry.vehicles?.[vehicleId];

                const cachedAt =
                    Number(
                        mfLiveTrainingVerifyCache.get(
                            vehicleId
                        ) || 0
                    );

                return !(
                    vehicleId &&
                    isAuthoritativeLivePoliceTrainingEntry(entry) &&
                    now - cachedAt <=
                        MF_LIVE_TRAINING_VERIFY_CACHE_MS
                );
            });

        // Prefer entries already believed to be ordinary, then unknown IDs.
        // Stale known-trained entries are checked last because specialist IRVs
        // should not be consumed merely to make normal attendance faster.
        const ordered = [
            // Verify anything already selected first. This allows the normal
            // Police requirement counter to reject a manually or previously
            // selected specialist IRV before deciding whether more units are
            // still needed.
            ...unverified.filter(checkbox => checkbox.checked),
            ...unverified.filter(checkbox => {
                const entry =
                    getRegistryEntryForMissionCheckbox(
                        checkbox,
                        registry
                    ).entry;

                return !!entry &&
                    !isKnownProtectedTrainedPoliceIrvEntry(entry);
            }),
            ...unverified.filter(checkbox => {
                return !getRegistryEntryForMissionCheckbox(
                    checkbox,
                    registry
                ).entry;
            }),
            ...unverified.filter(checkbox => {
                return isKnownProtectedTrainedPoliceIrvEntry(
                    getRegistryEntryForMissionCheckbox(
                        checkbox,
                        registry
                    ).entry
                );
            })
        ].filter((checkbox, index, array) => {
            return array.indexOf(checkbox) === index;
        });

        const checkedVerificationCount =
            candidates.filter(checkbox => checkbox.checked).length;

        const pageLimit =
            Math.min(
                MF_ORDINARY_IRV_VERIFY_MAX_PAGES,
                Math.max(
                    checkedVerificationCount + 24,
                    checkedVerificationCount +
                        ordinaryVehiclesRequired * 6
                )
            );

        const pagesToRead =
            ordered.slice(0, pageLimit);

        let pagesRead = 0;
        let changed = false;

        for (
            let offset = 0;
            offset < pagesToRead.length;
            offset += MF_ORDINARY_IRV_VERIFY_BATCH_SIZE
        ) {
            const batch = pagesToRead.slice(
                offset,
                offset + MF_ORDINARY_IRV_VERIFY_BATCH_SIZE
            );

            const results = await Promise.all(
                batch.map(async checkbox => {
                    const vehicleId =
                        getMissionVehicleId(checkbox);

                    try {
                        const response = await fetch(
                            `/vehicles/${vehicleId}/zuweisung`,
                            {
                                credentials: 'include',
                                cache: 'no-store',
                                headers: {
                                    Accept: 'text/html,application/xhtml+xml'
                                }
                            }
                        );

                        if (!response.ok) return null;

                        return {
                            checkbox,
                            vehicleId,
                            parsed:
                                parseLivePoliceTrainingAssignments(
                                    await response.text(),
                                    vehicleId
                                )
                        };
                    } catch (_error) {
                        return null;
                    }
                })
            );

            results.filter(result => result?.parsed?.assignmentScanComplete).forEach(result => {
                const existing =
                    registry.vehicles?.[result.vehicleId] || {};

                registry.vehicles[result.vehicleId] = {
                    ...existing,
                    vehicleId:
                        result.vehicleId,
                    vehicleName:
                        existing.vehicleName ||
                        getVehicleDebugName(result.checkbox),
                    vehicleTypeId:
                        String(
                            getVehicleTypeIdentifiers(
                                result.checkbox
                            )[0] ||
                            result.parsed.detectedVehicleTypeId ||
                            existing.vehicleTypeId ||
                            '8'
                        ),
                    assignedPersonnelCount:
                        result.parsed.assignedPersonnelCount,
                    assignmentScanComplete:
                        result.parsed.assignmentScanComplete,
                    personnelRowsSeen:
                        result.parsed.personnelRowsSeen,
                    trainingCounts: {
                        ...(
                            existing.trainingCounts &&
                            typeof existing.trainingCounts === 'object'
                                ? existing.trainingCounts
                                : {}
                        ),
                        ...result.parsed.trainingCounts
                    },
                    trainingCombinationCounts: {
                        ...(
                            existing.trainingCombinationCounts &&
                            typeof existing.trainingCombinationCounts === 'object'
                                ? existing.trainingCombinationCounts
                                : {}
                        ),
                        ...result.parsed.trainingCombinationCounts
                    },
                    updatedAt:
                        Date.now(),
                    source:
                        `${MF_STRICT_TRAINING_SOURCE_PREFIX}ordinary-${String(source || 'update').toLowerCase()}-v10676`
                };

                mfLiveTrainingVerifyCache.set(
                    result.vehicleId,
                    Date.now()
                );

                pagesRead += 1;
                changed = true;
            });

            if (changed) {
                savePersonnelTrainingRegistry(registry);
            }

            if (
                !hasUnverifiedCheckedVehicles() &&
                countVerifiedOrdinary() >=
                ordinaryVehiclesRequired
            ) {
                break;
            }
        }

        return {
            refreshed: changed,
            pagesRead,
            verifiedOrdinaryVehicles:
                countVerifiedOrdinary(),
            required:
                ordinaryVehiclesRequired
        };
    }

    async function prepareTrainedPersonnelRegistryForRows(
        rows,
        source = 'UPDATE'
    ) {
        const requirements = [];

        (Array.isArray(rows) ? rows : []).forEach(row => {
            if (!row?.isTrainedPersonnelRequirement) return;
            (row.personnelTrainingRequirements || []).forEach(requirement => {
                requirements.push(requirement);
            });
        });

        const irvRequirements = requirements.filter(requirement => {
            return requirement?.requirementType !==
                'armed_response_atc_vehicle';
        });

        const armedResponseRequirements = requirements.filter(requirement => {
            return requirement?.requirementType ===
                'armed_response_atc_vehicle';
        });

        const irv = await refreshPoliceInspectorRegistryFromLiveVehicles(
            irvRequirements,
            source
        );
        const armedResponse = await refreshArmedResponseRegistryFromLiveVehicles(
            armedResponseRequirements,
            source
        );

        return {
            irv,
            armedResponse
        };
    }

    async function preparePoliceVehicleSafetyForRows(
        rows,
        source = 'UPDATE'
    ) {
        const trained =
            await prepareTrainedPersonnelRegistryForRows(
                rows,
                source
            );

        const ordinary =
            await refreshOrdinaryPoliceRegistryFromLiveVehicles(
                rows,
                source
            );

        return {
            trained,
            ordinary
        };
    }

    function getRegistryTrainingCountsForCheckbox(
        checkbox,
        registry
    ) {
        const vehicleId =
            getMissionVehicleId(
                checkbox
            );

        const registryMatch =
            getRegistryEntryForMissionCheckbox(
                checkbox,
                registry
            );

        const entry =
            registryMatch.entry;

        return {
            vehicleId,
            entry:
                entry ||
                null,
            trainingCounts:
                entry &&
                typeof entry.trainingCounts ===
                    'object'
                    ? entry.trainingCounts
                    : {}
        };
    }

    function getRemainingTrainedPersonnelRequirements(
        requirements,
        selectedCheckboxes,
        registry
    ) {
        const remaining =
            new Map();

        (
            Array.isArray(requirements)
                ? requirements
                : []
        ).forEach(requirement => {
            remaining.set(
                requirement.code,
                {
                    ...requirement,
                    remaining:
                        getTrainingRequirementPersonnelTarget(
                            requirement
                        )
                }
            );
        });

        (
            Array.isArray(
                selectedCheckboxes
            )
                ? selectedCheckboxes
                : []
        ).forEach(checkbox => {
            const {
                entry
            } =
                getRegistryTrainingCountsForCheckbox(
                    checkbox,
                    registry
                );

            remaining.forEach(
                requirement => {
                    requirement.remaining =
                        Math.max(
                            0,
                            requirement.remaining -
                            getTrainingRequirementContribution(
                                requirement,
                                entry
                            )
                        );
                }
            );
        });

        return Array.from(
            remaining.values()
        );
    }

    function areTrainedPersonnelRequirementsSatisfied(
        requirements
    ) {
        const registry =
            readPersonnelTrainingRegistry();

        const selected =
            getVehicleCheckboxSnapshot().filter(
                checkbox => checkbox.checked
            );

        return getRemainingTrainedPersonnelRequirements(
            requirements,
            selected,
            registry
        ).every(
            requirement =>
                requirement.remaining <= 0
        );
    }

    function getTrainedVehicleSelectionScore(
        remaining,
        registryEntry
    ) {
        let usefulCoverage = 0;
        let twoPersonProfileMatches = 0;
        let rawContribution = 0;

        (Array.isArray(remaining) ? remaining : [])
            .forEach(requirement => {
                if (
                    !requirement ||
                    requirement.remaining <= 0
                ) {
                    return;
                }

                const contribution =
                    getTrainingRequirementContribution(
                        requirement,
                        registryEntry
                    );

                usefulCoverage += Math.min(
                    requirement.remaining,
                    contribution
                );

                rawContribution += contribution;

                if (contribution >= 2) {
                    twoPersonProfileMatches++;
                }
            });

        if (usefulCoverage <= 0) {
            return 0;
        }

        // Coverage remains the primary goal. For otherwise equal candidates,
        // a vehicle carrying two qualified personnel always ranks above a
        // one-person fallback, including when only one person remains needed.
        return (
            usefulCoverage * 10000 +
            twoPersonProfileMatches * 100 +
            Math.min(rawContribution, 99)
        );
    }

    function selectVehiclesForTrainedPersonnelRequirements(
        requirements,
        source = 'UPDATE'
    ) {
        const registry =
            readPersonnelTrainingRegistry();

        const registryVehicleCount =
            Object.keys(
                registry.vehicles ||
                {}
            ).length;

        const selected =
            getVehicleCheckboxSnapshot().filter(
                checkbox => checkbox.checked
            );

        let remaining =
            getRemainingTrainedPersonnelRequirements(
                requirements,
                selected,
                registry
            );

        const initiallySatisfied =
            remaining.every(
                requirement =>
                    requirement.remaining <= 0
            );

        if (initiallySatisfied) {
            return {
                satisfied:
                    true,
                selectedVehicles:
                    0,
                remaining,
                registryVehicleCount
            };
        }

        const readyCandidates =
            sortVehicleCheckboxesByBestArrival(
                getVehicleCheckboxSnapshot().filter(checkbox => {
                    if (
                        checkbox.disabled ||
                        checkbox.checked
                    ) {
                        return false;
                    }

                    const {
                        entry
                    } =
                        getRegistryTrainingCountsForCheckbox(
                            checkbox,
                            registry
                        );

                    return !!entry;
                })
            );

        let selectedVehicles = 0;
        const used =
            new Set();

        while (
            remaining.some(
                requirement =>
                    requirement.remaining > 0
            )
        ) {
            let bestCheckbox = null;
            let bestScore = 0;

            readyCandidates.forEach(
                checkbox => {
                    if (
                        used.has(checkbox)
                    ) {
                        return;
                    }

                    const {
                        entry
                    } =
                        getRegistryTrainingCountsForCheckbox(
                            checkbox,
                            registry
                        );

                    const score =
                        getTrainedVehicleSelectionScore(
                            remaining,
                            entry
                        );

                    if (
                        score >
                        bestScore
                    ) {
                        bestScore =
                            score;

                        bestCheckbox =
                            checkbox;
                    }
                }
            );

            if (
                !bestCheckbox ||
                bestScore <= 0
            ) {
                break;
            }

            used.add(
                bestCheckbox
            );

            if (
                clickVehicleElement(
                    bestCheckbox
                )
            ) {
                selectedVehicles++;

                const {
                    entry
                } =
                    getRegistryTrainingCountsForCheckbox(
                        bestCheckbox,
                        registry
                    );

                remaining =
                    remaining.map(
                        requirement => {
                            return {
                                ...requirement,
                                remaining:
                                    Math.max(
                                        0,
                                        requirement.remaining -
                                        getTrainingRequirementContribution(
                                            requirement,
                                            entry
                                        )
                                    )
                            };
                        }
                    );

                if (
                    mfDebugEnabled
                ) {
                    debugLog(
                        'TRAINED VEHICLE CLICK',
                        `${source} | ${getVehicleDebugName(bestCheckbox)} | score=${bestScore} | remaining=${remaining.map(item => `${item.label}:${item.remaining}`).join(', ')}`
                    );
                }
            }
        }

        return {
            satisfied:
                remaining.every(
                    requirement =>
                        requirement.remaining <= 0
                ),
            selectedVehicles,
            remaining,
            registryVehicleCount
        };
    }


    function getPoliceOfficerVehicleRequirement(
        requirementName,
        personnelRequired
    ) {
        const cleaned = String(requirementName || '')
            .replace(/\s+/g, ' ')
            .trim();
        const required = Math.max(
            0,
            parseInt(personnelRequired, 10) || 0
        );

        if (
            required <= 0 ||
            !/^(?:Required\s+)?Police\s+Officer(?:s)?$/i.test(cleaned)
        ) {
            return null;
        }

        return {
            unitName: 'Police Car',
            stillNeeded: Math.ceil(required / 2),
            personnelRequired: required,
            personnelPerVehicle: 2
        };
    }

    function normaliseOperationalRequirementRows(rows) {
        return (Array.isArray(rows) ? rows : []).map(row => {
            if (!row || row.isTrainedPersonnelRequirement) return row;

            const sarConversion =
                getSarPersonnelVehicleRequirement(
                    row.unitName,
                    row.stillNeeded
                );

            if (sarConversion) {
                return {
                    ...row,
                    unitName:
                        sarConversion.unitName,
                    stillNeeded:
                        sarConversion.stillNeeded,
                    personnelRequirement:
                        sarConversion.personnelRequirement,
                    personnelPerVehicle:
                        sarConversion.personnelPerVehicle,
                    sarPersonnelConversion:
                        sarConversion,
                    convertedFromPersonnelRequirement:
                        true
                };
            }

            const conversion = getPoliceOfficerVehicleRequirement(
                row.unitName,
                row.stillNeeded
            );

            if (!conversion) return row;

            return {
                ...row,
                unitName: conversion.unitName,
                stillNeeded: conversion.stillNeeded,
                personnelRequirement:
                    `${conversion.personnelRequired} Police Officer${conversion.personnelRequired === 1 ? '' : 's'}`,
                personnelPerVehicle: conversion.personnelPerVehicle,
                convertedFromPersonnelRequirement: true
            };
        });
    }

    function getSupportedMissingPersonnelRowsFromText(
        text,
        options = {}
    ) {
        const silent = !!(options && options.silent);

        const personnelSegment =
            getMissingPersonnelSegment(
                text
            );

        if (!personnelSegment) {
            return [];
        }

        const rows = [];

        const sarPersonnelDefinitions = [
            {
                displayName:
                    'Search Technicians',
                namePattern:
                    'search\\s+technician(?:s)?'
            },
            {
                displayName:
                    'Search Advisors',
                namePattern:
                    'search\\s+advisor(?:s)?'
            },
            {
                displayName:
                    'SAR Commanders',
                namePattern:
                    'sar\\s+commander(?:s)?'
            }
        ];

        sarPersonnelDefinitions.forEach(
            definition => {
                const personnelRequired =
                    getNamedPersonnelCount(
                        personnelSegment,
                        definition.namePattern
                    );

                if (personnelRequired <= 0) {
                    return;
                }

                const conversion =
                    getSarPersonnelVehicleRequirement(
                        definition.displayName,
                        personnelRequired
                    );

                if (!conversion) {
                    return;
                }

                rows.push({
                    unitName:
                        conversion.unitName,
                    stillNeeded:
                        conversion.stillNeeded,
                    personnelRequirement:
                        conversion.personnelRequirement
                });

                if (
                    mfDebugEnabled &&
                    !silent
                ) {
                    debugLog(
                        'UPDATE PERSONNEL',
                        `${conversion.personnelRequirement} -> select ${conversion.unitName} x${conversion.stillNeeded} (${conversion.personnelPerVehicle} personnel per vehicle)`
                    );
                }
            }
        );

        // Police Cars normally carry 2 Police Officers.
        const policeOfficersNeeded =
            getNamedPersonnelCount(
                personnelSegment,
                'police\\s+officer(?:s)?'
            );

        if (policeOfficersNeeded > 0) {
            const policeCarsNeeded =
                Math.ceil(
                    policeOfficersNeeded /
                    2
                );

            rows.push({
                unitName:
                    'Police Car',
                stillNeeded:
                    policeCarsNeeded,
                personnelRequirement:
                    `${policeOfficersNeeded} Police Officer${policeOfficersNeeded === 1 ? '' : 's'}`
            });

            if (
                mfDebugEnabled &&
                !silent
            ) {
                debugLog(
                    'UPDATE PERSONNEL',
                    `${policeOfficersNeeded} Police Officer${policeOfficersNeeded === 1 ? '' : 's'} -> select Police Car x${policeCarsNeeded}`
                );
            }
        }

        // Coastguard Mud Rescue Units carry 5 Mud Rescue Operators each.
        const mudRescueOperatorsNeeded =
            getNamedPersonnelCount(
                personnelSegment,
                'mud\\s+rescue\\s+operator(?:s)?'
            );

        if (mudRescueOperatorsNeeded > 0) {
            const mudRescueUnitsNeeded =
                Math.ceil(
                    mudRescueOperatorsNeeded /
                    5
                );

            rows.push({
                unitName:
                    'Coastguard Mud Rescue Unit',
                stillNeeded:
                    mudRescueUnitsNeeded,
                personnelRequirement:
                    `${mudRescueOperatorsNeeded} Mud Rescue Operator${mudRescueOperatorsNeeded === 1 ? '' : 's'}`
            });

            if (
                mfDebugEnabled &&
                !silent
            ) {
                debugLog(
                    'UPDATE PERSONNEL',
                    `${mudRescueOperatorsNeeded} Mud Rescue Operator${mudRescueOperatorsNeeded === 1 ? '' : 's'} -> select Coastguard Mud Rescue Unit x${mudRescueUnitsNeeded}`
                );
            }
        }

        return rows;
    }

    function hasSupportedMissingPersonnelUpdate(text) {
        return (
            getSupportedMissingPersonnelRowsFromText(
                text,
                { silent: true }
            ).length > 0 ||
            getSupportedTrainedPersonnelRequirementsFromText(
                text
            ).length > 0
        );
    }


    function getVisibleStaffingShortageText() {
        const scopes = getCurrentMissionAlertScopes();

        for (const scope of scopes) {
            const alerts = Array.from(
                scope.querySelectorAll(
                    '.alert-danger, div[id^="alert_danger_"], #missing_text'
                )
            );

            for (const alert of alerts) {
                try {
                    if (!isElementVisible(alert)) continue;
                } catch (error) {}

                const text = (
                    alert.innerText ||
                    alert.textContent ||
                    ''
                ).replace(/\s+/g, ' ').trim();

                if (!text) continue;

                const lower = text.toLowerCase();

                if (
                    lower.includes('not enough personnel') ||
                    lower.includes('not enough personal') ||
                    lower.includes('not enough staff') ||
                    lower.includes('insufficient personnel') ||
                    lower.includes('insufficient staff') ||
                    lower.includes('lacks personnel') ||
                    lower.includes('lacks staff') ||
                    lower.includes("doesn't have the right qualification") ||
                    lower.includes('does not have the right qualification') ||
                    lower.includes('right qualification')
                ) {
                    return text;
                }
            }
        }

        return '';
    }

    function detectAndLatchStaffingBlock(reason) {
        resetStaffingBlockForCurrentMission(reason);

        if (mfStaffingBlockActive) {
            return true;
        }

        const text =
            getVisibleStaffingShortageText() ||
            getInlinePersonnelQualificationAlertText();

        if (!text) return false;

        mfStaffingBlockActive = true;
        mfStaffingBlockText = text;

        vehicleLoadState.ready = false;
        changeDispatchBoxColor(false);

        updateStatusBox(
            'Staffing/qualification shortage detected. No more vehicles will be selected.'
        );

        if (mfDebugEnabled) {
            debugLog(
                'STAFFING GUARD',
                `BLOCKED | reason=${reason || 'unknown'} | ${text.slice(0, 350)}`
            );
        }

        try {
            recordIssueEvent(
                'STAFFING GUARD BLOCKED',
                {
                    reason: reason || 'unknown',
                    text: text.slice(0, 500)
                },
                true
            );
        } catch (error) {}

        return true;
    }


    function selectVehicleUnits(originalName, mappedName, amount, source) {
        if (!isCurrentMissionExecutionOwner('vehicle selection')) {
            const blockedRequired = Math.max(
                0,
                parseInt(amount, 10) || 0
            );

            return {
                assigned: 0,
                required: blockedRequired,
                missing: blockedRequired,
                skipped: true,
                staleMissionBlocked: true
            };
        }

        if (
            detectAndLatchStaffingBlock(
                `before-select-${String(source || 'unknown')}`
            )
        ) {
            return {
                assigned: 0,
                required: Math.max(
                    0,
                    parseInt(amount, 10) || 0
                ),
                missing: Math.max(
                    0,
                    parseInt(amount, 10) || 0
                ),
                skipped: true,
                staffingBlocked: true
            };
        }

        const required = Math.max(0, parseInt(amount, 10) || 0);
        const selectionSource = String(source || 'UNKNOWN').toUpperCase();
        const key = buildSelectionKey(selectionSource, originalName, mappedName, required);

        if (required <= 0) {
            return { assigned: 0, required, missing: 0, skipped: true };
        }

        if (processedSelectionKeys.has(key)) {
            if (mfDebugEnabled) {
                debugLog('SELECT SKIP', `${selectionSource} already processed ${originalName} -> ${mappedName} x${required}`);
            }
            return { assigned: 0, required, missing: 0, skipped: true };
        }

        processedSelectionKeys.add(key);

        const checkboxes = getMatchingVehicleCheckboxes(originalName, mappedName);
        let assigned = 0;

        if (mfDebugEnabled) {
            debugLog('SELECT START', `${selectionSource} | ${originalName} -> ${mappedName} | required=${required} | matching unchecked boxes=${checkboxes.length}`);
        }
        highDebugLog('SELECT DETAIL', `${selectionSource} | ${originalName} -> ${mappedName} | required=${required} | first=${checkboxes[0] ? getVehicleDebugName(checkboxes[0]) : 'none'}`);

        // V9.2.1: The requirement quantity decides dispatch. The visual counter never controls this loop.
        for (const checkbox of checkboxes.slice(0, required)) {
            if (
                detectAndLatchStaffingBlock(
                    `selection-loop-${selectionSource}`
                )
            ) {
                break;
            }

            if (mfDebugEnabled) debugLog('SELECT CLICK', `${selectionSource} | ${mappedName} | ${getVehicleDebugName(checkbox)}`);
            if (clickVehicleElement(checkbox)) {
                assigned += 1;
                const row = vehicleLoadState.rows.find(r => r.originalName === originalName && r.mappedName === mappedName);
                if (row) {
                    row.status = assigned >= required ? 'assigned' : 'retrying';
                    renderVehicleLoadList();
                }
            }
        }

        if (
            assigned < required &&
            !detectAndLatchStaffingBlock(
                `before-fallback-${selectionSource}`
            )
        ) {
            const fallback = findUnitButton(mappedName, originalName);

            if (fallback && !isVehicleElementAlreadySelected(fallback)) {
                if (mfDebugEnabled) debugLog('SELECT FALLBACK', `${selectionSource} | ${mappedName} | ${getVehicleDebugName(fallback)}`);
                if (fallback.matches && fallback.matches('input.vehicle_checkbox')) {
                    if (clickVehicleElement(fallback)) assigned += 1;
                    renderVehicleLoadList();
                } else {
                    while (assigned < required) {
                        if (!clickVehicleElement(fallback)) break;
                        assigned += 1;
                        renderVehicleLoadList();
                    }
                }
            } else if (mfDebugEnabled && assigned < required) {
                debugLog('SELECT MISSING', `${selectionSource} | ${mappedName} | assigned=${assigned}/${required}`);
            }
        }

        const selectedNow = countSelectedMatchingVehicles(originalName, mappedName);

        if (mfDebugEnabled) {
            debugLog('SELECT RESULT', `${selectionSource} | ${originalName} -> ${mappedName} | clicked=${assigned}/${required} | visual=${Math.min(selectedNow, required)}/${required}`);
        }

        return {
            assigned,
            required,
            missing: Math.max(required - assigned, 0),
            skipped: false
        };
    }

    function hasAuthoritativeLiveMissionRequirementsPanel() {
        return getMissionAccessibleDocuments().some(
            candidateDocument => {
                try {
                    return Array.from(
                        candidateDocument.querySelectorAll(
                            'table[aria-label="Live mission requirements"], ' +
                            '#mc-map-command-toolkit-mission-requirements[data-mcms-requirements-panel="1"] table'
                        )
                    ).some(table => {
                        return (
                            isLiveMissionRequirementsTable(table) &&
                            isMissionElementVisible(table)
                        );
                    });
                } catch (_error) {
                    return false;
                }
            }
        );
    }

    function getOperationalRequirementTargetMode(item) {
        return item?.liveRequirementDetails?.dispatchTargetMode === 'shortage'
            ? 'shortage'
            : 'total';
    }

    async function processRequirementRows(requirementRows, sourceLabel) {
        let missingUnits = [];
        const trainedPersonnelMissing = [];

        if (
            hasAuthoritativeLiveMissionRequirementsPanel() &&
            sourceLabel !== 'live mission requirements'
        ) {
            requirementRows = readMissionUpdateRows();
            sourceLabel = 'live mission requirements';

            if (mfDebugEnabled) {
                debugLog(
                    'UNIT FINDER LIVE AUTHORITY',
                    `Using ${requirementRows.length} current live requirement row(s); static mission-help rows were ignored.`
                );
            }
        }

        requirementRows = normaliseOperationalRequirementRows(
            requirementRows
        );

        updateStatusBox(`Processing ${sourceLabel} requirements...`);

        await preparePoliceVehicleSafetyForRows(
            requirementRows,
            sourceLabel
        );

        for (const item of requirementRows) {
            if (
                detectAndLatchStaffingBlock(
                    `process-${sourceLabel}`
                )
            ) {
                break;
            }

            const unitText = item.unitName;

            if (
                item
                    .isTrainedPersonnelRequirement
            ) {
                const requirements =
                    item
                        .personnelTrainingRequirements ||
                    [];

                const trainedVehicleTarget =
                    getTrainedPersonnelVehicleTarget(
                        requirements
                    );

                addOrUpdateVehicleRow(
                    unitText,
                    'Assigned trained vehicles',
                    trainedVehicleTarget,
                    'pending',
                    0
                );

                renderVehicleLoadList();

                await refreshPoliceInspectorRegistryFromLiveVehicles(
                    requirements,
                    sourceLabel
                );

                const result =
                    selectVehiclesForTrainedPersonnelRequirements(
                        requirements,
                        sourceLabel
                    );

                const largestRemaining =
                    result.remaining.reduce(
                        (
                            maximum,
                            requirement
                        ) => Math.max(
                            maximum,
                            Math.max(
                                0,
                                parseInt(
                                    requirement.remaining,
                                    10
                                ) || 0
                            )
                        ),
                        0
                    );

                const selectedCount =
                    Math.max(
                        0,
                        trainedVehicleTarget -
                        largestRemaining
                    );

                addOrUpdateVehicleRow(
                    unitText,
                    'Assigned trained vehicles',
                    trainedVehicleTarget,
                    result.satisfied
                        ? 'assigned'
                        : (
                            selectedCount > 0
                                ? 'retrying'
                                : 'missing'
                        ),
                    selectedCount
                );

                renderVehicleLoadList();

                if (!result.satisfied) {
                    trainedPersonnelMissing.push(
                        result.registryVehicleCount > 0
                            ? result.remaining
                                .filter(requirement => requirement.remaining > 0)
                                .map(requirement => `${requirement.label} x${requirement.remaining}`)
                                .join(', ')
                            : 'No trained-vehicle register was found. Run Personnel Assignment in Preview or Assign mode to build it.'
                    );
                }

                continue;
            }

            // Final shared safety net. Even if MissionChief changes a parser
            // layout and a minimum-statistic row reaches this stage, it must
            // never be selected, retried or reported as a missing unit.
            if (shouldIgnoreRequiredMinimumRequirement(unitText)) {
                continue;
            }

            const parsedAmount = parseInt(item.stillNeeded, 10);
            const replacedItemText = resolveUnitName(unitText);
            const targetMode = getOperationalRequirementTargetMode(item);
            const matchingSelectedAtStart =
                countSelectedMatchingVehicles(
                    unitText,
                    replacedItemText
                );
            const effectiveRequired =
                targetMode === 'shortage'
                    ? matchingSelectedAtStart + parsedAmount
                    : parsedAmount;

            if (mfDebugEnabled) {
                debugLog(
                    'PROCESS ROW',
                    `${unitText} -> ${replacedItemText} | target=${parsedAmount} | mode=${targetMode} | effective total=${effectiveRequired}`
                );
            }

            const selectedBefore = Math.min(
                matchingSelectedAtStart,
                effectiveRequired
            );
            const remainingToSelect = Math.max(
                0,
                effectiveRequired - selectedBefore
            );

            addOrUpdateVehicleRow(
                unitText,
                replacedItemText,
                effectiveRequired,
                remainingToSelect > 0 ? 'pending' : 'assigned',
                selectedBefore
            );
            renderVehicleLoadList();

            let selectionResult = null;
            if (remainingToSelect > 0) {
                selectionResult = selectVehicleUnits(
                    unitText,
                    replacedItemText,
                    remainingToSelect,
                    sourceLabel
                );
            }

            const selectedFromDom = Math.min(
                countSelectedMatchingVehicles(
                    unitText,
                    replacedItemText
                ),
                effectiveRequired
            );
            const selectedFromClicks = Math.min(
                effectiveRequired,
                selectedBefore + Math.max(
                    0,
                    parseInt(selectionResult?.assigned, 10) || 0
                )
            );
            const visualSelected = Math.max(
                selectedFromDom,
                selectedFromClicks
            );
            const status = visualSelected >= effectiveRequired
                ? 'assigned'
                : visualSelected > 0
                    ? 'retrying'
                    : 'missing';

            addOrUpdateVehicleRow(
                unitText,
                replacedItemText,
                effectiveRequired,
                status,
                visualSelected
            );
            renderVehicleLoadList();

            if (visualSelected < effectiveRequired) {
                missingUnits.push({
                    unitName: unitText,
                    stillNeeded: effectiveRequired - visualSelected,
                    requiredTotal: effectiveRequired
                });
            }
        }

        renderVehicleLoadList();

        if (mfStaffingBlockActive) {
            changeDispatchBoxColor(false);
            return false;
        }

        if (trainedPersonnelMissing.length > 0) {
            changeDispatchBoxColor(false);
            updateStatusBox(
                'A required trained Police IRV is still missing.'
            );

            originalAlert.call(
                window,
                `Final missing units:\n\n${trainedPersonnelMissing.join('\n')}`
            );

            return false;
        }

        if (missingUnits.length > 0) {
            // V10.6.48 parity guard:
            // Manual Unit Finder naturally waits while MissionChief loads the
            // missing-vehicle list. Auto Mode must wait for the same bounded
            // retry before it is allowed to run Mission Update or Dispatch.
            return await retryMissingUnits(
                missingUnits
            );
        }

        changeDispatchBoxColor(true);
        return true;
    }

    async function processVehicles(vehicleList) {
        const listItems = vehicleList.querySelectorAll('li.class-x');
        const requirementRows = [];

        listItems.forEach(item => {
            const unitText = [...item.childNodes]
                .filter(node => node.nodeType === Node.TEXT_NODE)
                .map(node => node.textContent.trim())[0];

            if (!unitText) return;

            const requiredAmount = parseInt(item.getAttribute('data-amount'), 10);
            if (!Number.isFinite(requiredAmount) || requiredAmount <= 0) return;

            requirementRows.push({
                unitName: unitText,
                stillNeeded: requiredAmount
            });
        });

        return processRequirementRows(requirementRows, 'fallback vehicle list');
    }

    async function retryMissingUnits(missingUnits) {
        if (!isCurrentMissionExecutionOwner('missing-unit retry')) {
            return false;
        }

        if (
            detectAndLatchStaffingBlock(
                'before-missing-unit-retry'
            )
        ) {
            updateStatusBox(
                'Staffing shortage detected. Missing-unit retry cancelled.'
            );
            changeDispatchBoxColor(false);
            return false;
        }

        const retryMissionId =
            getCurrentMissionIdForQueueRestart();

        const missingRows = missingUnits.map(unit => {
            if (typeof unit === 'string') {
                return {
                    unitName: unit,
                    stillNeeded: 1,
                    requiredTotal: 1
                };
            }

            const stillNeeded =
                Math.max(
                    1,
                    parseInt(
                        unit.stillNeeded,
                        10
                    ) || 1
                );

            const requiredTotal =
                Math.max(
                    stillNeeded,
                    parseInt(
                        unit.requiredTotal,
                        10
                    ) || stillNeeded
                );

            return {
                unitName: unit.unitName,
                stillNeeded,
                requiredTotal
            };
        });

        updateStatusBox('Retrying missing units...');

        missingRows.forEach(
            unit =>
                setVehicleStatus(
                    unit.unitName,
                    'retrying'
                )
        );

        renderVehicleLoadList();

        const loadingBar =
            document.querySelector(
                'a.btn-warning.missing_vehicles_load'
            );

        let timedOut = false;

        if (loadingBar) {
            try {
                loadingBar.click();
            } catch (_error) {}

            const retryStartedAt =
                Date.now();

            const retryTimeoutMs =
                20000;

            while (
                isLoadingBarVisible() &&
                Date.now() - retryStartedAt <
                    retryTimeoutMs
            ) {
                if (
                    autoModeRunning &&
                    isManualAutoStopActive()
                ) {
                    updateStatusBox(
                        'Missing-unit retry stopped.'
                    );
                    changeDispatchBoxColor(false);
                    return false;
                }

                const currentMissionId =
                    getCurrentMissionIdForQueueRestart();

                if (
                    retryMissionId &&
                    currentMissionId &&
                    currentMissionId !==
                        retryMissionId
                ) {
                    updateStatusBox(
                        'Mission changed during missing-unit retry. Selection cancelled.'
                    );

                    changeDispatchBoxColor(false);
                    return false;
                }

                await wait(250);
            }

            timedOut =
                isLoadingBarVisible();

            updateStatusBox(
                timedOut
                    ? 'Vehicle-list loading timed out. Running one final bounded retry...'
                    : 'Loading completed. Retrying missing units...'
            );
        }

        const stillMissing = [];

        for (
            const unit of
            missingRows
        ) {
            if (
                detectAndLatchStaffingBlock(
                    'during-missing-unit-retry'
                )
            ) {
                changeDispatchBoxColor(false);
                return false;
            }

            const currentMissionId =
                getCurrentMissionIdForQueueRestart();

            if (
                retryMissionId &&
                currentMissionId &&
                currentMissionId !==
                    retryMissionId
            ) {
                updateStatusBox(
                    'Mission changed before the missing-unit retry completed.'
                );

                changeDispatchBoxColor(false);
                return false;
            }

            const mappedName =
                resolveUnitName(
                    unit.unitName
                );

            // Recalculate from the current checked vehicles. Never use the
            // stale amount captured before MissionChief loaded more rows.
            // This is the key guard that stops Auto Mode selecting additional
            // units when another pass already satisfied the requirement.
            const selectedBefore =
                Math.min(
                    countSelectedMatchingVehicles(
                        unit.unitName,
                        mappedName
                    ),
                    unit.requiredTotal
                );

            const remainingNow =
                Math.max(
                    0,
                    unit.requiredTotal -
                    selectedBefore
                );

            if (
                remainingNow > 0
            ) {
                selectVehicleUnits(
                    unit.unitName,
                    mappedName,
                    remainingNow,
                    'RETRY'
                );
            }

            const selectedAfter =
                Math.min(
                    countSelectedMatchingVehicles(
                        unit.unitName,
                        mappedName
                    ),
                    unit.requiredTotal
                );

            if (
                selectedAfter >=
                unit.requiredTotal
            ) {
                setVehicleStatus(
                    unit.unitName,
                    'assigned'
                );
            } else {
                setVehicleStatus(
                    unit.unitName,
                    'missing'
                );

                stillMissing.push(
                    `${unit.unitName} x${
                        unit.requiredTotal -
                        selectedAfter
                    }`
                );
            }

            if (mfDebugEnabled) {
                debugLog(
                    'RETRY CAP',
                    `${unit.unitName} -> ${mappedName} | required total=${unit.requiredTotal} | selected before=${selectedBefore} | remaining now=${remainingNow} | selected after=${selectedAfter}`
                );
            }
        }

        renderVehicleLoadList();

        if (
            stillMissing.length ===
            0
        ) {
            changeDispatchBoxColor(true);
            return true;
        }

        changeDispatchBoxColor(false);

        if (!autoModeRunning) {
            alert(
                `${
                    timedOut
                        ? 'Final missing units after vehicle-list timeout'
                        : 'Final missing units'
                }:\n\n${stillMissing.join('\n')}`
            );
        } else {
            updateStatusBox(
                'Auto Mode: missing units. Will dispatch to skip.'
            );
        }

        return false;
    }

    function isLoadingBarVisible() {
        const loadingBar = document.querySelector('a.missing_vehicles_load');
        return loadingBar && getComputedStyle(loadingBar).display !== 'none';
    }

    function findLegacyVehicleRequirementList() {
        const vehicleHeadings = document.querySelectorAll('h4');

        for (const heading of vehicleHeadings) {
            if (heading.textContent.trim() !== 'Vehicles') continue;

            let nextElem = heading.nextElementSibling;

            while (nextElem && nextElem.tagName !== 'UL') {
                nextElem = nextElem.nextElementSibling;
            }

            if (nextElem && nextElem.tagName === 'UL') {
                return nextElem;
            }
        }

        return null;
    }

    function applyLatePatientCount(patientCount, sourceLabel) {
        const required = Math.max(0, parseInt(patientCount, 10) || 0);

        if (required <= 0) return false;

        const alreadySelected = countSelectedMatchingVehicles('Ambulance', 'Ambulance x 01');
        const stillNeeded = Math.max(required - alreadySelected, 0);

        vehicleLoadState.patients = required;

        addOrUpdateVehicleRow(
            'Ambulance',
            'Ambulance x 01',
            required,
            stillNeeded > 0 ? 'pending' : 'assigned',
            Math.min(alreadySelected, required)
        );

        if (stillNeeded > 0) {
            if (mfDebugEnabled) {
                debugLog('LATE PATIENT', `${sourceLabel || 'retry'} found ${required} patient(s); selecting ${stillNeeded} remaining ambulance(s).`);
            }

            selectVehicleUnits('Ambulance', 'Ambulance x 01', stillNeeded, 'PATIENT-LATE');
        }

        const selectedNow = Math.min(
            countSelectedMatchingVehicles('Ambulance', 'Ambulance x 01'),
            required
        );

        vehicleLoadState.ambulances = selectedNow;

        addOrUpdateVehicleRow(
            'Ambulance',
            'Ambulance x 01',
            required,
            selectedNow >= required ? 'assigned' : 'missing',
            selectedNow
        );

        renderVehicleLoadList();

        if (selectedNow >= required) {
            updateStatusBox(`Late patient data loaded: ${required} ambulance(s) selected.`);
            changeDispatchBoxColor(true);
            return true;
        }

        updateStatusBox(`Late patient data loaded, but only ${selectedNow}/${required} ambulance(s) were selected.`);
        changeDispatchBoxColor(false);
        return false;
    }

    async function recoverLateMissionRequirements(initialPatientCount) {
        const delays = [1200, 1500, 1800, 2200];
        let lastPatientCount = Math.max(0, parseInt(initialPatientCount, 10) || 0);

        updateStatusBox('No requirements found yet. Waiting for patient/mission data to finish loading...');

        for (let index = 0; index < delays.length; index += 1) {
            if (isManualAutoStopActive()) return false;
            if (!isMissionPage()) return false;

            await wait(delays[index]);

            const attempt = index + 1;
            const patientCount = findPatientCount();

            if (mfDebugEnabled) {
                debugLog(
                    'ZERO LIVE RETRY',
                    `Attempt ${attempt}/${delays.length} | patients=${patientCount} | previous=${lastPatientCount}`
                );
            }

            if (patientCount > 0) {
                return applyLatePatientCount(patientCount, `attempt ${attempt}`);
            }

            const visibleFallbackRows = parseVisibleMissionRequirementRows();

            if (visibleFallbackRows.length > 0) {
                updateStatusBox(`Late visible requirements found: ${visibleFallbackRows.length} row(s).`);
                await processRequirementRows(visibleFallbackRows, 'late visible fallback');
                return true;
            }

            const legacyVehicleList = findLegacyVehicleRequirementList();

            if (legacyVehicleList) {
                updateStatusBox('Late fallback vehicle list found. Processing...');
                await processVehicles(legacyVehicleList);
                return true;
            }

            // Re-fetch the mission help once after the page has had time to settle.
            if (attempt === 3) {
                const retryLiveRows = await readLiveMissionRequirements();

                if (retryLiveRows.length > 0) {
                    if (mfDebugEnabled) {
                        debugLog('ZERO LIVE RETRY', `Retry fetch found ${retryLiveRows.length} live requirement row(s).`);
                    }

                    await processRequirementRows(retryLiveRows, 'retry live mission help');
                    return true;
                }
            }

            lastPatientCount = patientCount;
        }

        if (mfDebugEnabled) {
            debugLog('ZERO LIVE RETRY', 'No patient or vehicle requirements appeared after all retries.');
        }

        return false;
    }

    const MF_ALLY_PENDING_KEY =
        'mf_ally_steal_pending_v10_5_8';

    const MF_ALLY_PENDING_MAX_AGE_MS =
        45000;

    let mfAllyResumeActive = false;

    // Remove temporary diagnostic data from the test builds.
    try {
        localStorage.removeItem(
            'mf_ally_steal_targeted_debug_v10_5_7'
        );
        localStorage.removeItem(
            'mf_ally_steal_targeted_debug_v10_5_8'
        );
    } catch (error) {}

    function safeAllyDebugText(
        value,
        max = 500
    ) {
        return String(value ?? '')
            .replace(/\s+/g, ' ')
            .trim()
            .slice(0, max);
    }

    function describeAllyDebugElement(
        element
    ) {
        if (!element) return null;

        const vehicleLink =
            element.matches?.(
                'a[href^="/vehicles/"]'
            )
                ? element
                : element.querySelector?.(
                    'a[href^="/vehicles/"]'
                );

        return {
            id:
                element.id || '',
            title:
                safeAllyDebugText(
                    element.getAttribute?.(
                        'title'
                    ) || '',
                    120
                ),
            href:
                safeAllyDebugText(
                    element.getAttribute?.(
                        'href'
                    ) ||
                    vehicleLink?.getAttribute?.(
                        'href'
                    ) ||
                    '',
                    180
                ),
            text:
                safeAllyDebugText(
                    element.textContent ||
                    element.innerText ||
                    '',
                    240
                ),
            connected:
                element.isConnected !== false,
            visible:
                isAllyStealElementVisible(
                    element
                )
        };
    }

    function safeAllyDebugObject(value) {
        try {
            return JSON.stringify(value);
        } catch (error) {
            return '';
        }
    }

    // Temporary diagnostics are disabled in the final build.
    function allyStealDebugLog() {}
    function allyStealDebugSnapshot() {}
    function startAllyStealDebugObserver() {}
    function resetAllyStealDebugLog() {}
    function renderAllyStealDebugLog() {}
    async function copyAllyStealDebugLog() {}

    function readAllyStealPendingState() {
        let pending = null;

        try {
            pending = JSON.parse(
                sessionStorage.getItem(
                    MF_ALLY_PENDING_KEY
                ) ||
                localStorage.getItem(
                    MF_ALLY_PENDING_KEY
                ) ||
                'null'
            );
        } catch (error) {
            pending = null;
        }

        if (
            !pending ||
            typeof pending !== 'object'
        ) {
            return null;
        }

        const age =
            Date.now() -
            Number(
                pending.clickedAt ||
                pending.startedAt ||
                0
            );

        if (
            !Number.isFinite(age) ||
            age < 0 ||
            age > MF_ALLY_PENDING_MAX_AGE_MS
        ) {
            clearAllyStealPendingState(
                'stale pending state'
            );
            return null;
        }

        return pending;
    }

    function writeAllyStealPendingState(
        pending
    ) {
        const encoded =
            JSON.stringify(pending);

        try {
            sessionStorage.setItem(
                MF_ALLY_PENDING_KEY,
                encoded
            );
        } catch (error) {}

        // LocalStorage is a fallback in case MissionChief replaces the
        // mission iframe rather than merely reloading the same document.
        try {
            localStorage.setItem(
                MF_ALLY_PENDING_KEY,
                encoded
            );
        } catch (error) {}

        allyStealDebugLog(
            'PENDING STATE SAVED',
            pending
        );
    }

    function clearAllyStealPendingState(
        reason = ''
    ) {
        try {
            sessionStorage.removeItem(
                MF_ALLY_PENDING_KEY
            );
        } catch (error) {}

        try {
            localStorage.removeItem(
                MF_ALLY_PENDING_KEY
            );
        } catch (error) {}

        if (reason) {
            allyStealDebugLog(
                'PENDING STATE CLEARED',
                reason
            );
        }
    }

    function getAllyStealAccessibleDocuments() {
        const documents = [];

        const addDocument = candidate => {
            try {
                if (
                    candidate &&
                    candidate.documentElement &&
                    !documents.includes(
                        candidate
                    )
                ) {
                    documents.push(candidate);
                }
            } catch (error) {}
        };

        addDocument(document);

        try {
            addDocument(
                window.parent?.document
            );
        } catch (error) {}

        try {
            addDocument(
                window.top?.document
            );
        } catch (error) {}

        // Include any same-origin MissionChief iframe documents owned by
        // the parent/top page.
        [...documents].forEach(ownerDocument => {
            try {
                ownerDocument
                    .querySelectorAll('iframe')
                    .forEach(frame => {
                        try {
                            addDocument(
                                frame.contentDocument
                            );
                        } catch (error) {}
                    });
            } catch (error) {}
        });

        return documents;
    }

    function isAllyStealElementVisible(
        element
    ) {
        if (
            !element ||
            element.isConnected === false
        ) {
            return false;
        }

        try {
            const ownerWindow =
                element.ownerDocument
                    ?.defaultView ||
                window;

            const style =
                ownerWindow.getComputedStyle(
                    element
                );

            if (
                style.display === 'none' ||
                style.visibility === 'hidden' ||
                Number(style.opacity) === 0
            ) {
                return false;
            }

            const rect =
                element.getBoundingClientRect();

            return (
                rect.width > 0 &&
                rect.height > 0
            );
        } catch (error) {
            return true;
        }
    }

    function getAllAllyStealSuccessAlerts() {
        const alerts = [];
        const seen = new Set();

        getAllyStealAccessibleDocuments()
            .forEach(searchDocument => {
                try {
                    searchDocument
                        .querySelectorAll(
                            '.alert.alert-success, [id^="alert_success_"]'
                        )
                        .forEach(alert => {
                            if (
                                seen.has(alert)
                            ) {
                                return;
                            }

                            seen.add(alert);
                            alerts.push(alert);
                        });
                } catch (error) {}
            });

        return alerts;
    }

    function getAllyStealParentModalCloseCandidates() {
        const candidates = [];
        const seen = new Set();

        const addCandidate = element => {
            if (
                !element ||
                seen.has(element)
            ) {
                return;
            }

            seen.add(element);
            candidates.push(element);
        };

        // Strongest match: the modal that directly contains this mission
        // frame. The log showed the Close control is outside the mission
        // document, in this parent Vue modal.
        try {
            const frameElement =
                window.frameElement;

            const frameModal =
                frameElement?.closest(
                    '.vm--modal, .modal, .lightbox'
                );

            // Current MissionChief close control.
            addCandidate(
                frameModal?.querySelector(
                    'button#lightbox_close_inside[aria-label="Close"]'
                )
            );

            addCandidate(
                frameModal?.querySelector(
                    '#lightbox_close_inside'
                )
            );

            // Older MissionChief close controls retained as fallbacks.
            addCandidate(
                frameModal?.querySelector(
                    '.control-btn-container span.lightbox-close[title="Close"]'
                )
            );

            addCandidate(
                frameModal?.querySelector(
                    'span.lightbox-close[title="Close"]'
                )
            );
        } catch (error) {}

        getAllyStealAccessibleDocuments()
            .forEach(searchDocument => {
                try {
                    searchDocument
                        .querySelectorAll(
                            'button#lightbox_close_inside[aria-label="Close"], ' +
                            '#lightbox_close_inside, ' +
                            '.vm--modal button.close[aria-label="Close"], ' +
                            '.vm--modal .control-btn-container span.lightbox-close[title="Close"], ' +
                            '.vm--modal span.lightbox-close[title="Close"], ' +
                            '.control-btn-container span.lightbox-close[title="Close"], ' +
                            'span.lightbox-close[title="Close"]'
                        )
                        .forEach(addCandidate);

                    // Last-resort locator for the visual × icon. Click its
                    // surrounding button rather than the inner span.
                    Array.from(
                        searchDocument.querySelectorAll(
                            'span[aria-hidden="true"]'
                        )
                    )
                        .filter(
                            icon =>
                                (
                                    icon.textContent ||
                                    ''
                                ).trim() === '×'
                        )
                        .map(
                            icon =>
                                icon.closest(
                                    'button#lightbox_close_inside, button.close[aria-label="Close"]'
                                )
                        )
                        .forEach(addCandidate);
                } catch (error) {}
            });

        return candidates.sort(
            (left, right) =>
                Number(
                    isAllyStealElementVisible(
                        right
                    )
                ) -
                Number(
                    isAllyStealElementVisible(
                        left
                    )
                )
        );
    }

    async function clickAllyStealParentMissionClose() {
        for (
            let attempt = 1;
            attempt <= 12;
            attempt++
        ) {
            const candidates =
                getAllyStealParentModalCloseCandidates();

            allyStealDebugLog(
                `PARENT CLOSE SEARCH ${attempt}`,
                candidates.map(
                    describeAllyDebugElement
                )
            );

            const closeButton =
                candidates.find(
                    isAllyStealElementVisible
                ) ||
                candidates[0] ||
                null;

            if (!closeButton) {
                await wait(250);
                continue;
            }

            // The pending state is cleared before clicking because a
            // successful parent-modal close unloads this mission document.
            clearAllyStealPendingState(
                'dispatch confirmed; closing parent mission lightbox'
            );

            try {
                closeButton.scrollIntoView({
                    block: 'center',
                    inline: 'center'
                });
            } catch (error) {}

            allyStealDebugLog(
                'PARENT CLOSE BUTTON CLICK',
                describeAllyDebugElement(
                    closeButton
                )
            );

            try {
                closeButton.click();
            } catch (error) {
                try {
                    const ownerWindow =
                        closeButton.ownerDocument
                            ?.defaultView ||
                        window;

                    [
                        'pointerdown',
                        'mousedown',
                        'pointerup',
                        'mouseup',
                        'click'
                    ].forEach(type => {
                        closeButton.dispatchEvent(
                            new ownerWindow.MouseEvent(
                                type,
                                {
                                    bubbles: true,
                                    cancelable: true,
                                    view: ownerWindow
                                }
                            )
                        );
                    });
                } catch (fallbackError) {
                    allyStealDebugLog(
                        'PARENT CLOSE CLICK ERROR',
                        {
                            message:
                                fallbackError?.message ||
                                String(
                                    fallbackError
                                )
                        }
                    );
                    return false;
                }
            }

            // This document may be unloaded immediately after the click.
            await wait(400);

            try {
                if (
                    !closeButton.isConnected ||
                    !isAllyStealElementVisible(
                        closeButton
                    )
                ) {
                    return true;
                }
            } catch (error) {
                return true;
            }

            // The click was issued against the exact visible parent Close
            // control. Treat it as successful even if the current iframe
            // remains alive long enough to reach this line.
            return true;
        }

        return false;
    }

    async function resumeAllyStealAfterDispatchRefresh(
        source = 'unknown'
    ) {
        if (mfAllyResumeActive) {
            return false;
        }

        const pending =
            readAllyStealPendingState();

        if (!pending) {
            return false;
        }

        mfAllyResumeActive = true;

        try {
            startAllyStealDebugObserver();

            allyStealDebugLog(
                'RESUME AFTER REFRESH',
                {
                    source,
                    pending,
                    href:
                        window.location.href,
                    missionName:
                        getCurrentMissionName(),
                    missionId:
                        getCurrentMissionIdForQueueRestart(),
                    isTopWindow:
                        MF_IS_TOP_WINDOW,
                    hasFrameElement:
                        !!window.frameElement,
                    accessibleDocuments:
                        getAllyStealAccessibleDocuments()
                            .length
                }
            );

            updateStatusBox(
                `Ally Steal: resumed after refresh. Waiting for ${pending.vehicleName || 'Fire Officer'} confirmation...`
            );

            const elapsed =
                Date.now() -
                Number(
                    pending.clickedAt ||
                    Date.now()
                );

            if (elapsed < 2000) {
                await wait(
                    2000 - elapsed
                );
            }

            const identity = {
                name:
                    pending.vehicleName ||
                    'Fire Officer',
                vehicleId:
                    pending.vehicleId ||
                    '',
                href:
                    pending.vehicleId
                        ? `/vehicles/${pending.vehicleId}`
                        : (
                            pending.vehicleHref ||
                            ''
                        )
            };

            const existingAlertIds =
                new Set(
                    Array.isArray(
                        pending.existingAlertIds
                    )
                        ? pending.existingAlertIds
                        : []
                );

            const successAlert =
                await waitForAllyStealDispatchSuccess(
                    identity,
                    existingAlertIds,
                    15000
                );

            if (!successAlert) {
                allyStealDebugLog(
                    'RESUME SUCCESS ALERT TIMEOUT',
                    {
                        identity,
                        alerts:
                            getAllAllyStealSuccessAlerts()
                                .map(
                                    describeAllyDebugElement
                                )
                    }
                );

                clearAllyStealPendingState(
                    'success alert not found after reload'
                );

                updateStatusBox(
                    `Ally Steal dispatched, but no matching success alert was found for ${identity.name}.`
                );

                return false;
            }

            allyStealDebugLog(
                'RESUME SUCCESS ALERT MATCHED',
                describeAllyDebugElement(
                    successAlert
                )
            );

            updateStatusBox(
                `Ally Steal: ${identity.name} dispatch confirmed. Closing mission...`
            );

            const closed =
                await clickAllyStealParentMissionClose();

            allyStealDebugLog(
                'RESUME PARENT CLOSE RESULT',
                {
                    closed
                }
            );

            if (!closed) {
                clearAllyStealPendingState(
                    'parent close button not found'
                );

                updateStatusBox(
                    'Ally Steal dispatched successfully, but the parent mission Close button was not found.'
                );

                return false;
            }

            updateStatusBox(
                `Ally Steal complete: ${identity.name} dispatched and mission closed.`
            );

            return true;
        } finally {
            mfAllyResumeActive = false;
        }
    }

    async function handleAllySteal() {
        resetAllyStealDebugLog();
        startAllyStealDebugObserver();

        allyStealDebugLog(
            'START',
            {
                script:
                    '10.5.7-ALLY-STEAL-TARGETED-DEBUG',
                href:
                    window.location.href,
                missionName:
                    getCurrentMissionName(),
                missionId:
                    getCurrentMissionIdForQueueRestart()
            }
        );

        allyStealDebugSnapshot(
            'before vehicle loading'
        );

        updateStatusBox(
            'Ally Steal: loading available Fire Officers...'
        );

        // Keep this separate from Unit Finder so no mission requirement,
        // patient, update, or automatic vehicle logic is run.
        clearSelectionGuards();

        await ensureVehicleListLoaded();

        allyStealDebugSnapshot(
            'after vehicle loading'
        );

        const originalName = 'Fire Officer';
        const mappedName = resolveUnitName(originalName);

        // Ally Steal must dispatch only one Fire Officer. Keep one already
        // selected Fire Officer when present and untick every other vehicle.
        const selectedFireOfficerBoxes =
            getAllMatchingVehicleCheckboxes(
                originalName,
                mappedName,
                true
            ).filter(checkbox => checkbox.checked);

        const fireOfficerToKeep =
            selectedFireOfficerBoxes[0] || null;

        getVehicleCheckboxSnapshot().filter(
            checkbox => checkbox.checked
        ).forEach(checkbox => {
            if (checkbox === fireOfficerToKeep) return;
            checkbox.click();
        });

        await wait(250);

        allyStealDebugSnapshot(
            'after clearing other selections'
        );

        let selectedFireOfficers =
            countSelectedMatchingVehicles(
                originalName,
                mappedName
            );

        // Select one Fire Officer when none was already ticked.
        if (selectedFireOfficers < 1) {
            const result = selectVehicleUnits(
                originalName,
                mappedName,
                1,
                'ALLY STEAL'
            );

            allyStealDebugLog(
                'SELECT RESULT',
                result
            );

            await wait(350);

            selectedFireOfficers =
                countSelectedMatchingVehicles(
                    originalName,
                    mappedName
                );

            if (
                result.staffingBlocked ||
                selectedFireOfficers < 1
            ) {
                updateStatusBox(
                    'Ally Steal stopped: no available Fire Officer was found.'
                );
                return false;
            }
        }

        resetVehicleLoadState();

        addOrUpdateVehicleRow(
            originalName,
            mappedName,
            1,
            'assigned',
            1
        );

        vehicleLoadState.ready = true;
        renderVehicleLoadList();

        const selectedFireOfficerCheckbox =
            getAllMatchingVehicleCheckboxes(
                originalName,
                mappedName,
                true
            ).find(checkbox => checkbox.checked);

        if (!selectedFireOfficerCheckbox) {
            updateStatusBox(
                'Ally Steal stopped: the selected Fire Officer could not be identified.'
            );
            return false;
        }

        const selectedVehicleIdentity =
            getAllyStealSelectedVehicleIdentity(
                selectedFireOfficerCheckbox
            );

        allyStealDebugLog(
            'SELECTED VEHICLE IDENTITY',
            selectedVehicleIdentity
        );

        allyStealDebugLog(
            'SELECTED CHECKBOX',
            describeAllyDebugElement(
                selectedFireOfficerCheckbox
            )
        );

        allyStealDebugSnapshot(
            'Fire Officer selected'
        );

        const existingSuccessAlertIds = new Set(
            Array.from(
                document.querySelectorAll(
                    'div.alert.alert-success[id^="alert_success_"]'
                )
            )
            .map(alert => alert.id)
            .filter(Boolean)
        );

        allyStealDebugLog(
            'EXISTING SUCCESS ALERT IDS',
            Array.from(existingSuccessAlertIds)
        );

        updateStatusBox(
            `Ally Steal: ${selectedVehicleIdentity.name || 'Fire Officer'} selected. Dispatching...`
        );

        await wait(400);

        const dispatchButton =
            await getAllyStealNormalDispatchButton();

        if (!dispatchButton) {
            allyStealDebugLog(
                'DISPATCH BUTTON NOT FOUND'
            );
            allyStealDebugSnapshot(
                'dispatch button lookup failed'
            );

            changeDispatchBoxColor(false);
            updateStatusBox(
                'Ally Steal stopped: the normal Dispatch button was not ready.'
            );
            return false;
        }

        allyStealDebugLog(
            'DISPATCH BUTTON FOUND',
            describeAllyDebugElement(
                dispatchButton
            )
        );

        try {
            dispatchButton.scrollIntoView({
                block: 'center',
                inline: 'center'
            });
        } catch (error) {}

        const pendingState = {
            startedAt:
                Date.now(),
            clickedAt:
                Date.now(),
            missionId:
                getCurrentMissionIdForQueueRestart(),
            missionName:
                getCurrentMissionName(),
            vehicleName:
                selectedVehicleIdentity.name ||
                'Fire Officer',
            vehicleId:
                selectedVehicleIdentity.vehicleId ||
                '',
            vehicleHref:
                selectedVehicleIdentity.href ||
                '',
            existingAlertIds:
                Array.from(
                    existingSuccessAlertIds
                )
        };

        writeAllyStealPendingState(
            pendingState
        );

        try {
            dispatchButton.click();

            allyStealDebugLog(
                'DISPATCH CLICK CALLED',
                {
                    button:
                        describeAllyDebugElement(
                            dispatchButton
                        ),
                    pendingState
                }
            );
        } catch (error) {
            clearAllyStealPendingState(
                'dispatch click threw an error'
            );

            allyStealDebugLog(
                'DISPATCH CLICK ERROR',
                {
                    name:
                        error?.name || '',
                    message:
                        error?.message ||
                        String(error)
                }
            );

            updateStatusBox(
                'Ally Steal stopped: the normal Dispatch button could not be clicked.'
            );

            return false;
        }

        updateStatusBox(
            'Ally Steal: Dispatch clicked. Mission refresh pending...'
        );

        // In case MissionChief updates the page without a full document
        // reload, this same instance also attempts the resume workflow.
        setTimeout(
            function() {
                resumeAllyStealAfterDispatchRefresh(
                    'same-document fallback'
                );
            },
            2200
        );

        // A full document refresh normally happens immediately after this
        // return. The pending state is then resumed by initialize().
        return true;
    }

    function readUnitFinderPatientRequirementRows() {
        // Unit Finder owns the initial mission-help attachment requirements,
        // but it must also honour the current patient cards. Reuse the proven
        // patient alert parser from Mission Update, then keep only rows that
        // came from visible current-mission "We need:" patient alerts. This
        // deliberately excludes the general Live Mission Requirements rows.
        return readMissionUpdateRows({
            silent: true
        }).filter(row => {
            return !!(
                row &&
                row.isPatientAlertFallback &&
                row.patientRequirementType &&
                Math.max(
                    0,
                    parseInt(
                        row.stillNeeded,
                        10
                    ) || 0
                ) > 0
            );
        });
    }

    function handleUnitFinderPatientRequirements() {
        const patientRows =
            readUnitFinderPatientRequirementRows();

        if (patientRows.length === 0) {
            return {
                found: false,
                satisfied: true,
                rows: []
            };
        }

        updateStatusBox(
            `Unit Finder: processing ${patientRows.length} current patient requirement row(s)...`
        );

        const satisfied =
            handleMissionUpdateUnits(
                false,
                patientRows,
                {
                    suppressUpdateLog: true
                }
            );

        return {
            found: true,
            satisfied: satisfied !== false,
            rows: patientRows
        };
    }

    async function handleCombinedLogic(options = {}) {
        if (!isCurrentMissionExecutionOwner('Unit Finder')) {
            return false;
        }

        synchroniseMissionInstanceState('Unit Finder start');

        const missionKeyAtStart =
            getLocalMissionInstanceKey();

        const vehicleListAlreadyLoaded =
            !!options.vehicleListAlreadyLoaded;

        const suppliedAttachmentPromise =
            options.attachmentRowsPromise &&
            typeof options.attachmentRowsPromise.then === 'function'
                ? options.attachmentRowsPromise
                : null;

        resetVehicleLoadState();
        resetStaffingBlockForCurrentMission(
            'Unit Finder start'
        );

        if (
            detectAndLatchStaffingBlock(
                'Unit Finder precheck'
            )
        ) {
            return;
        }

        if (mfDebugEnabled) {
            debugLog('START', `Unit Finder | Mission: ${getCurrentMissionName()}`, true);
        }
        changeDispatchBoxColor(false);
        updateStatusBox('Started V9 live Unit Finder...');

        if (!vehicleListAlreadyLoaded) {
            const vehicleLoadResult =
                await ensureVehicleListLoaded({
                    requireNonZero: true
                });

            if (!vehicleLoadResult.ready) {
                vehicleLoadState.ready = false;
                changeDispatchBoxColor(false);
                updateStatusBox(
                    'Unit Finder stopped: the complete vehicle list did not become stable.'
                );
                return false;
            }
        }

        if (
            missionKeyAtStart !==
            getLocalMissionInstanceKey()
        ) {
            updateStatusBox(
                'Mission changed while Unit Finder was loading. Previous mission cancelled.'
            );
            return;
        }

        // Keep the initial and update workflows separate:
        //   Unit Finder    -> mission-help attachment
        //                     Vehicle and Personnel Requirements
        //   Mission Update -> Live Mission Requirements panel
        //
        // The live panel can exist during the initial mission. It must not
        // prevent Unit Finder from fetching the mission-help attachment.

        if (
            mfDebugEnabled
        ) {
            debugLog(
                'UNIT FINDER SOURCE',
                'Mission-help attachment only: Vehicle and Personnel Requirements. Live Mission Requirements is reserved for Mission Update.'
            );
        }

        let patientCount = handlePatientSelector();
        const attachmentRows = suppliedAttachmentPromise
            ? await suppliedAttachmentPromise
            : await readLiveMissionRequirements();

        if (
            missionKeyAtStart !==
            getLocalMissionInstanceKey()
        ) {
            updateStatusBox(
                'Mission changed before Unit Finder selection. Previous mission requirements ignored.'
            );
            return;
        }

        // Patient cards can finish rendering while the attachment is being
        // fetched. Refresh the normal patient count once, then process the
        // explicit current-patient "We need:" rows before the mission rows.
        // Running the mission rows last ensures a missing mission unit cannot
        // be hidden by a successful patient-only pass.
        patientCount = Math.max(
            patientCount,
            handlePatientSelector()
        );

        const patientRequirementResult =
            handleUnitFinderPatientRequirements();

        const preservePatientFailure = result => {
            if (
                patientRequirementResult.found &&
                !patientRequirementResult.satisfied
            ) {
                changeDispatchBoxColor(false);
                return false;
            }

            return result;
        };

        if (attachmentRows.length > 0) {
            const missionRequirementsSatisfied =
                await processRequirementRows(
                    attachmentRows,
                    'MISSION HELP ATTACHMENT'
                );

            return preservePatientFailure(
                missionRequirementsSatisfied
            );
        }

        const visibleFallbackRows = parseVisibleMissionRequirementRows();

        if (visibleFallbackRows.length > 0) {
            updateStatusBox(`Visible fallback requirements found: ${visibleFallbackRows.length} row(s).`);

            if (mfDebugEnabled) {
                debugLog(
                    'UNIT FINDER ATTACHMENT FALLBACK',
                    'Mission-help attachment returned 0 rows, using visible mission requirements instead.'
                );
            }

            const missionRequirementsSatisfied =
                await processRequirementRows(
                    visibleFallbackRows,
                    'VISIBLE FALLBACK'
                );

            return preservePatientFailure(
                missionRequirementsSatisfied
            );
        }

        const vehicleList = findLegacyVehicleRequirementList();

        if (vehicleList) {
            updateStatusBox('Fallback vehicle list found. Processing...');

            const missionRequirementsSatisfied =
                await processVehicles(vehicleList);

            return preservePatientFailure(
                missionRequirementsSatisfied
            );
        }

        if (
            patientCount > 0 ||
            patientRequirementResult.found
        ) {
            if (patientRequirementResult.satisfied) {
                updateStatusBox(
                    'No mission vehicle rows found. Current patient requirements processed.'
                );
                changeDispatchBoxColor(true);
                return true;
            }

            updateStatusBox(
                'Current patient requirements are still missing units.'
            );
            changeDispatchBoxColor(false);
            return false;
        }

        // MissionChief sometimes opens the mission before its patient cards have
        // finished rendering. Do not immediately decide that the mission has no units.
        const recovered = await recoverLateMissionRequirements(patientCount);

        if (recovered) return;

        updateStatusBox('No live requirements or fallback vehicle list found after retrying.');
        changeDispatchBoxColor(false);
        renderVehicleLoadList();
    }

    function getActiveMissionInfoForAllySteal() {
        const candidates = Array.from(
            document.querySelectorAll(
                '#mission_general_info'
            )
        );

        return candidates.find(element => {
            const modal = element.closest(
                '.vm--modal, .modal, .lightbox'
            );

            return (
                isVisibleForQueueRestart(element) ||
                (
                    modal &&
                    isVisibleForQueueRestart(modal)
                )
            );
        }) || candidates[candidates.length - 1] || null;
    }

    function getAllyStealSelectedVehicleIdentity(
        checkbox
    ) {
        const row = checkbox?.closest('tr');

        const vehicleLink =
            row?.querySelector(
                'a[href^="/vehicles/"]'
            ) ||
            checkbox?.closest(
                'a[href^="/vehicles/"]'
            ) ||
            null;

        const href = (
            vehicleLink?.getAttribute('href') ||
            ''
        ).split('?')[0].trim();

        const linkName = (
            vehicleLink?.textContent ||
            vehicleLink?.innerText ||
            ''
        ).replace(/\s+/g, ' ').trim();

        const fallbackName = getVehicleDebugName(
            checkbox
        );

        const checkboxVehicleId =
            (
                (
                    checkbox?.id ||
                    ''
                ).match(
                    /^vehicle_checkbox_(\d+)$/
                ) ||
                []
            )[1] ||
            checkbox?.getAttribute(
                'vehicle_id'
            ) ||
            checkbox?.getAttribute(
                'data-vehicle-id'
            ) ||
            checkbox?.value ||
            '';

        const vehicleId =
            (
                href.match(
                    /\/vehicles\/(\d+)/
                ) ||
                []
            )[1] ||
            (
                String(
                    checkboxVehicleId
                ).match(/^(\d+)$/) ||
                []
            )[1] ||
            '';

        return {
            name:
                linkName ||
                fallbackName ||
                'Fire Officer',
            href:
                href ||
                (
                    vehicleId
                        ? `/vehicles/${vehicleId}`
                        : ''
                ),
            vehicleId
        };
    }

    async function getAllyStealNormalDispatchButton(
        timeoutMs = 4000
    ) {
        const startedAt = Date.now();

        while (Date.now() - startedAt < timeoutMs) {
            const missionInfo =
                getActiveMissionInfoForAllySteal();

            const activeModal = missionInfo
                ? missionInfo.closest(
                    '.vm--modal, .modal, .lightbox'
                )
                : null;

            const candidates = Array.from(
                (
                    activeModal ||
                    document
                ).querySelectorAll(
                    'a#mission_alarm_btn'
                )
            );

            const dispatchButton =
                candidates.find(button => {
                    if (
                        !isVisibleForQueueRestart(button)
                    ) {
                        return false;
                    }

                    const disabled =
                        button.hasAttribute('disabled') ||
                        button.getAttribute(
                            'aria-disabled'
                        ) === 'true' ||
                        button.classList.contains(
                            'disabled'
                        );

                    if (disabled) return false;

                    const title = (
                        button.getAttribute('title') ||
                        ''
                    ).replace(/\s+/g, ' ')
                        .trim()
                        .toLowerCase();

                    const text = (
                        button.textContent ||
                        button.innerText ||
                        ''
                    ).replace(/\s+/g, ' ')
                        .trim()
                        .toLowerCase();

                    const amountBadge =
                        button.querySelector(
                            '#vehicle_amount'
                        );

                    const selectedAmount = parseInt(
                        (
                            amountBadge?.textContent ||
                            amountBadge?.innerText ||
                            '0'
                        ).replace(/[^0-9]/g, ''),
                        10
                    ) || 0;

                    return (
                        title.startsWith('dispatch') &&
                        !title.includes('next') &&
                        text.startsWith('dispatch') &&
                        selectedAmount >= 1
                    );
                });

            if (dispatchButton) {
                allyStealDebugLog(
                    'DISPATCH LOOKUP MATCH',
                    describeAllyDebugElement(
                        dispatchButton
                    )
                );

                return dispatchButton;
            }

            if (
                (Date.now() - startedAt) % 1000 <
                120
            ) {
                allyStealDebugLog(
                    'DISPATCH LOOKUP WAIT',
                    Array.from(
                        document.querySelectorAll(
                            '#mission_alarm_btn'
                        )
                    ).map(
                        describeAllyDebugElement
                    )
                );
            }

            await wait(100);
        }

        return null;
    }

    function allyStealSuccessAlertMatchesVehicle(
        alert,
        identity
    ) {
        if (!alert) return false;

        const text = (
            alert.textContent ||
            alert.innerText ||
            ''
        ).replace(/\s+/g, ' ').trim();

        if (
            !/has successfully been dispatched\.?$/i.test(
                text
            )
        ) {
            return false;
        }

        const vehicleLink =
            alert.querySelector(
                'a[href^="/vehicles/"]'
            );

        if (!vehicleLink) return false;

        const alertHref = (
            vehicleLink.getAttribute('href') ||
            ''
        ).split('?')[0].trim();

        const alertName = normaliseVehicleText(
            vehicleLink.textContent ||
            vehicleLink.innerText ||
            ''
        );

        const expectedName =
            normaliseVehicleText(
                identity?.name || ''
            );

        if (
            identity?.href &&
            alertHref === identity.href
        ) {
            return true;
        }

        if (
            identity?.vehicleId &&
            alertHref.includes(
                `/vehicles/${identity.vehicleId}`
            )
        ) {
            return true;
        }

        return (
            !!expectedName &&
            alertName === expectedName
        );
    }

    async function waitForAllyStealDispatchSuccess(
        identity,
        existingAlertIds,
        timeoutMs = 8000
    ) {
        const startedAt = Date.now();
        let lastAlertSignature = '';

        while (Date.now() - startedAt < timeoutMs) {
            const allAlerts =
                getAllAllyStealSuccessAlerts();

            const alertDiagnostics =
                allAlerts.map(alert => ({
                    element:
                        describeAllyDebugElement(
                            alert
                        ),
                    existedBefore:
                        !!alert.id &&
                        existingAlertIds.has(
                            alert.id
                        ),
                    visible:
                        isAllyStealElementVisible(
                            alert
                        ),
                    matchesVehicle:
                        allyStealSuccessAlertMatchesVehicle(
                            alert,
                            identity
                        )
                }));

            const signature =
                safeAllyDebugObject(
                    alertDiagnostics
                );

            if (
                signature !== lastAlertSignature
            ) {
                lastAlertSignature = signature;

                allyStealDebugLog(
                    'SUCCESS ALERT SCAN',
                    alertDiagnostics
                );
            }

            const matchingAlerts =
                allAlerts.filter(alert => {
                    if (
                        alert.id &&
                        existingAlertIds.has(
                            alert.id
                        )
                    ) {
                        return false;
                    }

                    return (
                        isAllyStealElementVisible(
                            alert
                        ) &&
                        allyStealSuccessAlertMatchesVehicle(
                            alert,
                            identity
                        )
                    );
                });

            if (matchingAlerts.length > 0) {
                return matchingAlerts[
                    matchingAlerts.length - 1
                ];
            }

            await wait(150);
        }

        allyStealDebugLog(
            'SUCCESS ALERT WAIT TIMEOUT',
            {
                timeoutMs,
                identity
            }
        );

        return null;
    }

    async function closeAllyStealMissionFromSuccessAlert(
        successAlert
    ) {
        const alertModal =
            successAlert?.closest(
                '.vm--modal, .modal, .lightbox'
            ) ||
            null;

        allyStealDebugLog(
            'CLOSE START',
            {
                successAlert:
                    describeAllyDebugElement(
                        successAlert
                    ),
                alertModal:
                    describeAllyDebugElement(
                        alertModal
                    )
            }
        );

        for (let attempt = 1; attempt <= 8; attempt++) {
            const missionInfo =
                getActiveMissionInfoForAllySteal();

            const activeModal =
                alertModal &&
                alertModal.isConnected &&
                isVisibleForQueueRestart(alertModal)
                    ? alertModal
                    : (
                        missionInfo?.closest(
                            '.vm--modal, .modal, .lightbox'
                        ) ||
                        null
                    );

            allyStealDebugLog(
                `CLOSE ATTEMPT ${attempt} MODAL`,
                describeAllyDebugElement(
                    activeModal
                )
            );

            if (!activeModal) {
                allyStealDebugLog(
                    `CLOSE ATTEMPT ${attempt}`,
                    'No active modal remained; treating mission as already closed.'
                );
                return true;
            }

            const closeButton =
                activeModal.querySelector(
                    '.control-btn-container span.lightbox-close[title="Close"]'
                ) ||
                activeModal.querySelector(
                    'span.lightbox-close[title="Close"]'
                );

            allyStealDebugLog(
                `CLOSE ATTEMPT ${attempt} BUTTON`,
                describeAllyDebugElement(
                    closeButton
                )
            );

            if (!closeButton) {
                allyStealDebugLog(
                    `CLOSE ATTEMPT ${attempt}`,
                    'Close button not found in selected modal.'
                );
                await wait(250);
                continue;
            }

            try {
                closeButton.scrollIntoView({
                    block: 'center',
                    inline: 'center'
                });
            } catch (error) {}

            try {
                closeButton.click();

                allyStealDebugLog(
                    `CLOSE ATTEMPT ${attempt} CLICK`,
                    'Native closeButton.click() called.'
                );
            } catch (error) {
                allyStealDebugLog(
                    `CLOSE ATTEMPT ${attempt} NATIVE ERROR`,
                    {
                        name:
                            error?.name || '',
                        message:
                            error?.message ||
                            String(error)
                    }
                );

                const fallbackResult =
                    realClickForQueueRestart(
                        closeButton
                    );

                allyStealDebugLog(
                    `CLOSE ATTEMPT ${attempt} FALLBACK`,
                    {
                        fallbackResult
                    }
                );
            }

            await wait(500);

            allyStealDebugLog(
                `CLOSE ATTEMPT ${attempt} AFTER WAIT`,
                {
                    modalConnected:
                        activeModal.isConnected,
                    modalVisible:
                        isVisibleForQueueRestart(
                            activeModal
                        ),
                    activeMission:
                        describeAllyDebugElement(
                            getActiveMissionInfoForAllySteal()
                        )
                }
            );

            if (
                !activeModal.isConnected ||
                !isVisibleForQueueRestart(
                    activeModal
                )
            ) {
                return true;
            }
        }

        allyStealDebugLog(
            'CLOSE FAILED',
            'All 8 close attempts finished with the mission modal still visible.'
        );

        return false;
    }


    function clickDispatchOnly() {
        // Proven fast MissionChief workflow:
        // dispatch selected vehicles and open the next mission in one
        // native action. Do not separately click Next Mission afterwards.
        const dispatchNextButton =
            Array.from(
                document.querySelectorAll(
                    'a.alert_next'
                )
            ).find(button => {
                if (
                    !button ||
                    !isElementVisible(button)
                ) {
                    return false;
                }

                if (
                    button.id ===
                    'mission_next_mission_btn'
                ) {
                    return false;
                }

                const disabled =
                    button.hasAttribute(
                        'disabled'
                    ) ||
                    button.getAttribute(
                        'aria-disabled'
                    ) === 'true' ||
                    button.classList.contains(
                        'disabled'
                    );

                return !disabled;
            }) ||
            null;

        if (dispatchNextButton) {
            try {
                dispatchNextButton.scrollIntoView({
                    block: 'center',
                    inline: 'center'
                });
            } catch (error) {}

            try {
                dispatchNextButton.click();
                return true;
            } catch (error) {
                return realClickForQueueRestart(
                    dispatchNextButton
                );
            }
        }

        // Next Mission (0) has no combined next destination.
        // Dispatch the final mission normally and let the established
        // final-queue restart workflow take over.
        const queueState =
            getNextMissionQueueState();

        const isLastMission =
            !!queueState?.exists &&
            queueState.count === 0;

        if (!isLastMission) {
            return false;
        }

        const finalDispatchButton =
            Array.from(
                document.querySelectorAll(
                    'a#mission_alarm_btn'
                )
            ).find(button => {
                if (
                    !button ||
                    !isElementVisible(button)
                ) {
                    return false;
                }

                const disabled =
                    button.hasAttribute(
                        'disabled'
                    ) ||
                    button.getAttribute(
                        'aria-disabled'
                    ) === 'true' ||
                    button.classList.contains(
                        'disabled'
                    );

                if (disabled) {
                    return false;
                }

                const title = (
                    button.getAttribute(
                        'title'
                    ) ||
                    ''
                )
                    .replace(/\s+/g, ' ')
                    .trim()
                    .toLowerCase();

                const visibleText = (
                    button.textContent ||
                    button.innerText ||
                    ''
                )
                    .replace(/\s+/g, ' ')
                    .trim()
                    .toLowerCase();

                return (
                    title.startsWith(
                        'dispatch'
                    ) &&
                    !title.includes(
                        'next'
                    ) &&
                    visibleText.startsWith(
                        'dispatch'
                    )
                );
            }) ||
            null;

        if (!finalDispatchButton) {
            return false;
        }

        try {
            finalDispatchButton.scrollIntoView({
                block: 'center',
                inline: 'center'
            });
        } catch (error) {}

        try {
            finalDispatchButton.click();
            return true;
        } catch (error) {
            return realClickForQueueRestart(
                finalDispatchButton
            );
        }
    }


    function clickDispatchAndShareOnly() {
        const dispatchShareButton =
            document.querySelector('a.alert_next_alliance') ||
            Array.from(document.querySelectorAll('a, button')).find(
                element => {
                    if (!element) return false;

                    const text = (
                        element.textContent ||
                        ''
                    ).replace(/\s+/g, ' ').trim().toLowerCase();

                    const title = (
                        element.getAttribute('title') ||
                        ''
                    ).replace(/\s+/g, ' ').trim().toLowerCase();

                    return text === 'dispatch & share' ||
                        text === 'dispatch and share' ||
                        text.includes('alarm and share') ||
                        title.includes('dispatch and share');
                }
            );

        if (!dispatchShareButton) return false;

        dispatchShareButton.click();
        return true;
    }

    function clickMissionDispatchByValue(
        missionCredits,
        reason
    ) {
        const credits = Number(missionCredits || 0);
        const shouldShare =
            credits > MF_SHARE_CREDIT_THRESHOLD;

        if (shouldShare) {
            // Dispatch & Share does not use MissionChief's combined
            // Dispatch-and-next control. Save the exact Next Mission target
            // before dispatch so Auto Mode can move on immediately after the
            // share refresh, without any post-dispatch upgrade wait.
            const advanceState =
                createAutoAdvanceAfterDispatchState(
                    reason || 'Auto Mode high-value mission',
                    'auto'
                );

            if (advanceState) {
                writeAutoAdvanceAfterDispatchState(
                    advanceState
                );
            }

            if (clickDispatchAndShareOnly()) {
                updateStatusBox(
                    `High-value mission (${credits.toLocaleString('en-GB')} credits): Dispatch & Share clicked. Moving to the next mission...`
                );

                if (advanceState) {
                    setTimeout(
                        function() {
                            resumeAutoAdvanceAfterDispatch(
                                'same-document Auto Mode Dispatch & Share'
                            );
                        },
                        800
                    );
                }

                return {
                    clicked: true,
                    shared: true,
                    advancePending:
                        !!advanceState
                };
            }

            clearAutoAdvanceAfterDispatchState(
                'Auto Mode Dispatch & Share unavailable'
            );
        }

        // Normal missions use MissionChief's native Dispatch & Next action.
        clearAutoAdvanceAfterDispatchState(
            'normal Auto Mode Dispatch & Next'
        );

        const clicked = clickDispatchOnly();

        return {
            clicked,
            shared: false,
            advancePending: false
        };
    }


    function triggerDispatchClick() {
        clearAutoAdvanceAfterDispatchState(
            'manual normal Dispatch uses native Dispatch-and-next'
        );

        if (clickDispatchOnly()) {
            updateStatusBox(
                'Dispatch & Next clicked. MissionChief is opening the next mission...'
            );
        } else {
            updateStatusBox(
                'Dispatch & Next button not found.'
            );

            console.error(
                'Dispatch & Next button not found.'
            );
        }
    }


    function triggerDispatchShareClick() {
        const advanceState =
            createAutoAdvanceAfterDispatchState(
                'manual Dispatch & Share',
                'manual'
            );

        writeAutoAdvanceAfterDispatchState(
            advanceState
        );

        if (clickDispatchAndShareOnly()) {
            updateStatusBox(
                advanceState
                    ? 'Dispatch & Share clicked. Waiting for refresh, then opening Next Mission...'
                    : 'Dispatch & Share clicked. No next mission is available.'
            );

            if (advanceState) {
                setTimeout(
                    function() {
                        resumeAutoAdvanceAfterDispatch(
                            'same-document manual Dispatch & Share'
                        );
                    },
                    800
                );
            }
        } else {
            clearAutoAdvanceAfterDispatchState(
                'manual Dispatch & Share button not found'
            );

            updateStatusBox(
                'Dispatch & Share button not found.'
            );

            console.error(
                'Dispatch & Share button not found.'
            );
        }
    }


    function getGenericMissingVehicleRowsFromText(
        text
    ) {
        const input =
            String(
                text ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        const marker =
            input.match(
                /Missing\s+Vehicles?\s*:\s*(.+)$/i
            );

        if (!marker) return [];

        const requirementText =
            marker[1]
                .replace(
                    /\s+(?:Missing\s+Personnel|We\s+need)\s*:.+$/i,
                    ''
                )
                .trim();

        const rows = [];

        const requirementRegex =
            /(\d+)\s*(?:x\s*)?([A-Za-z][A-Za-z0-9 /&()'’\-]+?)(?=,\s*\d+\s*(?:x\s*)?|\s+and\s+\d+\s*(?:x\s*)?|$)/gi;

        let match;

        while (
            (
                match =
                    requirementRegex.exec(
                        requirementText
                    )
            )
        ) {
            const amount =
                parseInt(
                    match[1],
                    10
                );

            const name =
                String(
                    match[2] ||
                    ''
                )
                    .replace(
                        /\s+/g,
                        ' '
                    )
                    .trim();

            if (
                !Number.isFinite(amount) ||
                amount <= 0 ||
                !name
            ) {
                continue;
            }

            // These have dedicated conversion logic below.
            if (
                /Police\s+Helicopter(?:s)?\s+or\s+Drone(?:s)?/i.test(
                    name
                ) ||
                /Seagoing\s+Vessel/i.test(
                    name
                ) ||
                /car(?:s)?\s+to\s+tow/i.test(
                    name
                )
            ) {
                continue;
            }

            rows.push({
                unitName:
                    name,
                stillNeeded:
                    amount
            });
        }

        return rows;
    }


    function isLiveMissionRequirementsTable(
        table
    ) {
        if (!table) {
            return false;
        }

        return !!(
            table.matches?.(
                'table[aria-label="Live mission requirements"]'
            ) &&
            table.closest?.(
                '#mc-map-command-toolkit-mission-requirements[data-mcms-requirements-panel="1"], ' +
                'section[data-mcms-requirements-panel="1"]'
            )
        );
    }

    function parseMissionRequirementNumber(
        value
    ) {
        const cleaned =
            String(
                value ??
                ''
            )
                .replace(
                    /,/g,
                    ''
                )
                .trim();

        if (
            !cleaned ||
            cleaned ===
                '?' ||
            cleaned ===
                '—' ||
            cleaned ===
                '-'
        ) {
            return null;
        }

        const match =
            cleaned.match(
                /-?\d+/
            );

        if (!match) {
            return null;
        }

        const parsed =
            parseInt(
                match[0],
                10
            );

        return Number.isFinite(
            parsed
        )
            ? parsed
            : null;
    }

    function parseMissionRequirementRangeUpperBound(
        value
    ) {
        const cleaned = String(
            value ?? ''
        )
            .replace(/\s+/g, ' ')
            .trim();

        const match = cleaned.match(
            /^(\d+)\s*(?:-|–|—|to)\s*(\d+)$/i
        );

        if (!match) {
            return null;
        }

        const lower = parseInt(match[1], 10);
        const upper = parseInt(match[2], 10);

        if (
            !Number.isFinite(lower) ||
            !Number.isFinite(upper)
        ) {
            return null;
        }

        return Math.max(
            0,
            lower,
            upper
        );
    }

    function getLiveRequirementCellText(
        row,
        selectors,
        fallbackIndex
    ) {
        for (
            const selector of
            selectors
        ) {
            const cell =
                row.querySelector(
                    selector
                );

            if (cell) {
                return (
                    cell.innerText ||
                    cell.textContent ||
                    ''
                )
                    .replace(
                        /\s+/g,
                        ' '
                    )
                    .trim();
            }
        }

        const cells =
            row.querySelectorAll(
                'td'
            );

        const fallbackCell =
            cells[
                fallbackIndex
            ];

        return (
            fallbackCell?.innerText ||
            fallbackCell?.textContent ||
            ''
        )
            .replace(
                /\s+/g,
                ' '
            )
            .trim();
    }

    function getLiveRequirementDispatchTarget(
        parsedRow
    ) {
        const required = Math.max(
            0,
            parseInt(
                parsedRow?.required,
                10
            ) || 0
        );

        const reportedStillNeeded = Math.max(
            0,
            parseInt(
                parsedRow?.stillNeeded,
                10
            ) || 0
        );

        const stillNeededText = String(
            parsedRow?.stillNeededText ?? ''
        )
            .replace(/\s+/g, ' ')
            .trim();

        // The live shortage remains authoritative whenever MissionChief gives
        // a number or bounded range. Only a literal unknown "?" falls back to
        // the Required total. The selection layer still subtracts matching
        // vehicles already selected before it clicks any additional units.
        if (stillNeededText === '?') {
            return required > 0
                ? required
                : reportedStillNeeded;
        }

        if (stillNeededText) {
            return reportedStillNeeded;
        }

        // Defensive fallback for a legacy or partial live row where the
        // Still Needed cell is absent rather than explicitly zero.
        return required > 0
            ? required
            : reportedStillNeeded;
    }

    function readLiveMissionRequirementRow(
        row
    ) {
        if (!row) {
            return null;
        }

        const cells =
            row.querySelectorAll(
                'td'
            );

        if (
            cells.length <
            2
        ) {
            return null;
        }

        const unitName =
            (
                cells[0].innerText ||
                cells[0].textContent ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        if (!unitName) {
            return null;
        }

        if (shouldIgnoreRequiredMinimumRequirement(unitName)) {
            return null;
        }

        const requiredText =
            getLiveRequirementCellText(
                row,
                [
                    'td[data-label="Required"]'
                ],
                1
            );

        const selectedText =
            getLiveRequirementCellText(
                row,
                [
                    'td[data-label="Selected"]'
                ],
                4
            );

        const stillNeededText =
            getLiveRequirementCellText(
                row,
                [
                    'td.mcms-req-still',
                    'td[data-label="Need"]',
                    'td[data-label="Still needed"]'
                ],
                5
            );

        const required =
            parseMissionRequirementNumber(
                requiredText
            );

        const selected =
            parseMissionRequirementNumber(
                selectedText
            );

        const explicitStillNeeded =
            parseMissionRequirementNumber(
                stillNeededText
            );

        const explicitStillNeededRange =
            parseMissionRequirementRangeUpperBound(
                stillNeededText
            );

        const rowState =
            String(
                row.getAttribute(
                    'data-row-state'
                ) ||
                ''
            )
                .trim()
                .toLowerCase();

        const title =
            String(
                row.getAttribute(
                    'title'
                ) ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        const requiresConfirmation =
            rowState ===
                'unresolved' ||
            /requires?\s+confirmation/i
                .test(
                    title
                ) ||
            stillNeededText ===
                '?' ||
            explicitStillNeededRange !==
                null;

        // A bounded unresolved value such as 0-3 is actionable. Use the
        // upper bound so Mission Update covers the worst-case shortage,
        // while a completely unknown naked '?' continues through the
        // existing trusted-row safety rules below.
        let stillNeeded =
            explicitStillNeededRange !== null
                ? explicitStillNeededRange
                : explicitStillNeeded;

        if (
            stillNeeded ===
                null &&
            requiresConfirmation
        ) {
            const isTrustedUnresolvedPublicOrderPersonnel =
                isPublicOrderPersonnelRequirementName(
                    unitName
                ) ||
                isPoliceSergeantPersonnelRequirementName(
                    unitName
                ) ||
                isPoliceInspectorPersonnelRequirementName(
                    unitName
                );

            const isTrustedUnresolvedSarPersonnel =
                required !== null &&
                !!getSarPersonnelVehicleRequirement(
                    unitName,
                    required
                );

            const isTrustedUnresolvedTowRequirement =
                required !== null &&
                isCarsToTowRequirementName(
                    unitName
                );

            if (
                (
                    isTrustedUnresolvedPublicOrderPersonnel ||
                    isTrustedUnresolvedSarPersonnel ||
                    isTrustedUnresolvedTowRequirement
                ) &&
                required !==
                    null
            ) {
                // V10.6.61/V10.6.63: Supported SAR/Public Order personnel and
                // Cars to tow scalar rows can legitimately stay unresolved as
                // "Need ?" while still showing an explicit Required count.
                // Trust only those narrow rules. Every other unresolved row
                // remains zero so Mission Update cannot resend the complete
                // original mission load.
                stillNeeded =
                    Math.max(
                        0,
                        required
                    );
            } else {
                // A '?' / unresolved general row is not a confirmed shortage.
                // Do not substitute the full Required value because that can
                // make Mission Update resend the entire original mission load.
                stillNeeded = 0;
            }
        }

        if (
            stillNeeded ===
                null &&
            !requiresConfirmation &&
            required !==
                null &&
            selected !==
                null
        ) {
            stillNeeded =
                Math.max(
                    0,
                    required -
                    selected
                );
        }

        if (
            stillNeeded ===
                null
        ) {
            stillNeeded =
                0;
        }

        return {
            unitName,
            required:
                Math.max(
                    0,
                    required ||
                    0
                ),
            selected:
                Math.max(
                    0,
                    selected ||
                    0
                ),
            stillNeeded:
                Math.max(
                    0,
                    stillNeeded
                ),
            rowState,
            requiresConfirmation,
            requiredText,
            selectedText,
            stillNeededText,
            title
        };
    }

    function isMissionUpdateTable(table) {
        if (!table) return false;

        if (
            isLiveMissionRequirementsTable(
                table
            )
        ) {
            return true;
        }

        const text = (table.textContent || '')
            .replace(/\s+/g, ' ')
            .trim()
            .toLowerCase();

        // Hard block the official mission help / full requirement table.
        // Mission Update must only read the live missing-units table on the mission page.
        if (text.includes('vehicle and personnel requirements')) return false;
        if (text.includes('average credits')) return false;
        if (text.includes('possible missions')) return false;

        // The update table contains a Still Needed / Still required style column.
        return text.includes('still needed')
            || text.includes('still required')
            || text.includes('needed') && text.includes('required');
    }


    function normaliseMissionAlertText(
        value
    ) {
        return String(
            value ||
            ''
        )
            .replace(
                /[\u200B-\u200D\uFEFF]/g,
                ''
            )
            .replace(
                /\u00A0/g,
                ' '
            )
            .replace(
                /\s+/g,
                ' '
            )
            .trim();
    }

    function getMissionUpdatePatientRequirementRule(
        unitName
    ) {
        const cleaned =
            String(
                unitName ||
                ''
            )
                .replace(
                    /\s+/g,
                    ' '
                )
                .trim();

        if (
            /^(?:Required\s+)?Ambulance\s+Officer(?:s)?$/i
                .test(cleaned)
        ) {
            return {
                type: 'ambulance-officer',
                unitName: 'Ambulance Officer',
                maximum: 1
            };
        }

        if (
            /^(?:Required\s+)?Mass\s+Casualty\s+Equipment(?:\s+Unit(?:s)?)?$/i
                .test(cleaned)
        ) {
            return {
                type: 'mass-casualty-equipment',
                unitName: 'Mass Casualty Equipment',
                maximum: 1
            };
        }

        if (
            /^(?:Required\s+)?Ambulance(?:s)?(?:\s+x\s*0?1)?$/i
                .test(cleaned)
        ) {
            return {
                type: 'ambulance',
                unitName: 'Ambulance x 01',
                maximum: null
            };
        }

        if (
            /^(?:Required\s+)?Critical\s+Care(?:\s+Team(?:s)?)?$/i
                .test(cleaned)
        ) {
            return {
                type: 'critical-care',
                unitName: 'Critical Care',
                maximum: null
            };
        }

        return null;
    }

    function normaliseMissionUpdatePatientRequirement(
        unitName,
        amount
    ) {
        const safeAmount =
            Math.max(
                0,
                parseInt(
                    amount,
                    10
                ) || 0
            );

        const rule =
            getMissionUpdatePatientRequirementRule(
                unitName
            );

        if (!rule) {
            return {
                unitName:
                    String(
                        unitName ||
                        ''
                    )
                        .replace(
                            /\s+/g,
                            ' '
                        )
                        .trim(),
                stillNeeded:
                    safeAmount,
                type:
                    '',
                capped:
                    false
            };
        }

        const normalisedAmount =
            Number.isFinite(
                rule.maximum
            )
                ? Math.min(
                    safeAmount,
                    rule.maximum
                )
                : safeAmount;

        return {
            unitName:
                rule.unitName,
            stillNeeded:
                normalisedAmount,
            type:
                rule.type,
            capped:
                normalisedAmount !==
                safeAmount
        };
    }

    function getPatientAlertGroupKey(
        element,
        fallbackIndex
    ) {
        const ownerDocument =
            element?.ownerDocument ||
            document;

        const documentKey =
            ownerDocument.URL ||
            'mission-document';

        const patientContainer =
            element?.closest?.(
                '.mission_patient, [id^="patient_"], [data-patient-id]'
            );

        if (patientContainer) {
            const identifier =
                patientContainer.id ||
                patientContainer.getAttribute(
                    'data-patient-id'
                ) ||
                patientContainer.getAttribute(
                    'patient_id'
                ) ||
                patientContainer.getAttribute(
                    'data-id'
                );

            if (identifier) {
                return (
                    `${documentKey}|patient:${identifier}`
                );
            }

            try {
                const patientContainers =
                    Array.from(
                        ownerDocument.querySelectorAll(
                            '.mission_patient, [id^="patient_"], [data-patient-id]'
                        )
                    );

                const containerIndex =
                    patientContainers.indexOf(
                        patientContainer
                    );

                if (
                    containerIndex >=
                    0
                ) {
                    return (
                        `${documentKey}|patient-index:${containerIndex}`
                    );
                }
            } catch (_error) {}
        }

        // Some MissionChief layouts place patient alerts outside a patient
        // wrapper. Keep each visible alert as its own patient requirement.
        // The previous code always returned group 0 here, which merged every
        // unwrapped patient and could produce the wrong scalable-unit count.
        const alertIdentifier =
            element?.id ||
            element?.getAttribute?.(
                'data-patient-id'
            ) ||
            element?.getAttribute?.(
                'data-id'
            );

        return (
            `${documentKey}|unscoped-patient:${alertIdentifier || Math.max(0, Number(fallbackIndex) || 0)}`
        );
    }

    function getCurrentMissionPatientAlertRoots(
        liveRequirementsTables,
        fallbackRoots
    ) {
        const roots = [];

        const addRoot = root => {
            if (
                root &&
                !roots.includes(root)
            ) {
                roots.push(root);
            }
        };

        const addMissionContainerForElement = element => {
            if (!element) return;

            const outerMissionWindow =
                element.closest?.(
                    '.vm--modal, .modal, .lightbox, #lightbox_box'
                );

            if (outerMissionWindow) {
                addRoot(outerMissionWindow);
                return;
            }

            const missionContent =
                element.closest?.(
                    '#iframe-inside-container, #mission_content, .mission_content'
                );

            if (missionContent) {
                addRoot(missionContent);
                return;
            }

            addRoot(
                element.ownerDocument ||
                document
            );
        };

        // The visible mission information is the strongest current-mission
        // marker. Prefer its modal/content container over a whole document.
        addMissionContainerForElement(
            getActiveVisibleMissionInfo()
        );

        (
            Array.isArray(liveRequirementsTables)
                ? liveRequirementsTables
                : []
        ).forEach(
            addMissionContainerForElement
        );

        // V10.6.63: The live requirements panel and patient cards can sit
        // in different containers/documents of the same current mission. The
        // fallback roots are already filtered by current-mission isolation, so
        // include them as well instead of dropping patient cards merely because
        // a live-panel root was found first.
        (
            Array.isArray(fallbackRoots)
                ? fallbackRoots
                : []
        ).forEach(addRoot);

        return roots;
    }

    function getVisiblePatientBadgeCountInRoots(
        roots
    ) {
        let highestCount = 0;

        (
            Array.isArray(roots)
                ? roots
                : []
        ).forEach(root => {
            try {
                root.querySelectorAll(
                    'span.badge, .badge'
                ).forEach(badge => {
                    if (
                        !isMissionElementVisible(
                            badge
                        )
                    ) {
                        return;
                    }

                    const text =
                        normaliseMissionAlertText(
                            badge.textContent ||
                            badge.innerText ||
                            ''
                        );

                    if (
                        !/patients?/i.test(
                            text
                        )
                    ) {
                        return;
                    }

                    const match =
                        text.match(/\d+/);

                    const count =
                        match
                            ? parseInt(
                                match[0],
                                10
                            ) || 0
                            : 0;

                    highestCount =
                        Math.max(
                            highestCount,
                            count
                        );
                });
            } catch (_error) {}
        });

        return highestCount;
    }

    function getLinkedVisiblePatientContainer(
        alertElement,
        roots
    ) {
        if (!alertElement) return null;

        const isInsideAcceptedRoot =
            element => {
                return (
                    Array.isArray(roots) &&
                    roots.some(root => {
                        try {
                            return (
                                root === element ||
                                root.contains(element)
                            );
                        } catch (_error) {
                            return false;
                        }
                    })
                );
            };

        const directContainer =
            alertElement.closest?.(
                '.mission_patient, [id^="patient_"], [data-patient-id], [patient_id]'
            );

        if (
            directContainer &&
            isInsideAcceptedRoot(
                directContainer
            ) &&
            isMissionElementVisible(
                directContainer
            )
        ) {
            return directContainer;
        }

        const alertId =
            String(
                alertElement.id ||
                ''
            );

        const patientIdMatch =
            alertId.match(
                /^patients?_missing_(\d+)/i
            );

        if (!patientIdMatch) {
            return null;
        }

        const patientId =
            patientIdMatch[1];

        const ownerDocument =
            alertElement.ownerDocument ||
            document;

        const escapedPatientId =
            typeof CSS !== 'undefined' &&
            typeof CSS.escape === 'function'
                ? CSS.escape(patientId)
                : patientId.replace(
                    /[^A-Za-z0-9_-]/g,
                    ''
                );

        const selectors = [
            `#patient_${escapedPatientId}`,
            `[data-patient-id="${escapedPatientId}"]`,
            `[patient_id="${escapedPatientId}"]`,
            `[data-id="${escapedPatientId}"]`
        ];

        for (const selector of selectors) {
            let candidate = null;

            try {
                candidate =
                    ownerDocument.querySelector(
                        selector
                    );
            } catch (_error) {}

            if (
                candidate &&
                isInsideAcceptedRoot(
                    candidate
                ) &&
                isMissionElementVisible(
                    candidate
                )
            ) {
                return candidate;
            }
        }

        return null;
    }

    function isCurrentMissionPatientAlert(
        alertElement,
        roots,
        hasLiveRequirementsPanel,
        visiblePatientBadgeCount
    ) {
        if (
            !alertElement ||
            !isMissionElementVisible(
                alertElement
            )
        ) {
            return false;
        }

        if (
            alertElement.closest?.(
                '#mission-finder-wrapper'
            )
        ) {
            return false;
        }

        const text =
            normaliseMissionAlertText(
                alertElement.textContent ||
                alertElement.innerText ||
                ''
            );

        if (
            !/\bWe\s+need\s*:/i.test(
                text
            )
        ) {
            return false;
        }

        // Keep the legacy behaviour when the dedicated live panel does not
        // exist. The stricter scope guard is specifically for the live-panel
        // route where stale previous-patient alerts were being picked up.
        if (!hasLiveRequirementsPanel) {
            return true;
        }

        if (
            getLinkedVisiblePatientContainer(
                alertElement,
                roots
            )
        ) {
            return true;
        }

        // Some MissionChief layouts temporarily place the alert outside the
        // patient card. Accept that fallback only when the current mission
        // container also has a visible positive Patients badge. A leftover
        // patient alert from a previous mission cannot then add an ambulance
        // to a Police-only Mission Update.
        return (
            Math.max(
                0,
                parseInt(
                    visiblePatientBadgeCount,
                    10
                ) || 0
            ) > 0
        );
    }

    function readMissionUpdateRows(options = {}) {
        if (!isCurrentMissionExecutionOwner('Mission Update requirement read')) {
            return [];
        }

        synchroniseMissionInstanceState('Mission Update read');

        const silent = !!(options && options.silent);
        const now = Date.now();
        const missionKey = getLocalMissionInstanceKey();

        if (
            silent &&
            missionKey === mfMissionUpdateRowsCache.missionKey &&
            now < mfMissionUpdateRowsCache.expiresAt
        ) {
            return mfMissionUpdateRowsCache.rows;
        }

        const missingRows = [];

        const missionUpdateContexts =
            getActiveMissionRequirementContexts();

        const missionUpdateRoots =
            Array.from(
                new Set(
                    missionUpdateContexts
                        .map(
                            context =>
                                context.root
                        )
                )
            );

        let tableLevel1PublicOrderRequired =
            0;

        let tableLevel2PublicOrderRequired =
            0;

        let tablePoliceSergeantRequired =
            0;

        let tablePoliceInspectorRequired =
            0;

        let tablePoliceMedicRequired =
            0;

        let tableRailwayPoliceRequired =
            0;

        let tableArmedResponseRequired =
            0;

        // V10.6.45 patient-source authority guard.
        // A confirmed Live Mission Requirements row owns that patient unit,
        // including an explicit/derived Need of 0. This prevents a stale
        // visible patient "We need" alert from resending Ambulances, Critical
        // Care, Ambulance Officers or Mass Casualty Equipment after the live
        // panel has already confirmed that no further unit is required.
        const livePatientRequirementStates =
            new Map();

        const discoveredUpdateTables =
            Array.from(
                new Set(
                    missionUpdateRoots
                        .flatMap(root => {
                            try {
                                return Array.from(
                                    root.querySelectorAll(
                                        '#mc-map-command-toolkit-mission-requirements[data-mcms-requirements-panel="1"] table[aria-label="Live mission requirements"], ' +
                                        'section[data-mcms-requirements-panel="1"] table[aria-label="Live mission requirements"], ' +
                                        'table.table-striped.table-condensed, table.table'
                                    )
                                );
                            } catch (_error) {
                                return [];
                            }
                        })
                )
            )
                .filter(
                    isMissionUpdateTable
                )
                .filter(
                    table =>
                        isMissionElementVisible(
                            table
                        )
                );

        const liveRequirementsTables =
            discoveredUpdateTables.filter(
                isLiveMissionRequirementsTable
            );

        const hasLiveRequirementsPanel =
            liveRequirementsTables.length >
            0;

        const updateTables =
            hasLiveRequirementsPanel
                ? liveRequirementsTables
                : discoveredUpdateTables;

        if (
            mfDebugEnabled &&
            !silent
        ) {
            const documentDescriptions =
                missionUpdateContexts
                    .map(
                        (
                            context,
                            index
                        ) => {
                            const url =
                                context.document
                                    ?.URL ||
                                'unknown';

                            return (
                                `${index + 1}:${url}` +
                                ` [${context.reasons.join(',')}]`
                            );
                        }
                    )
                    .join(' || ');

            debugLog(
                'UPDATE SCOPE',
                `contexts=${missionUpdateContexts.length} | ${documentDescriptions}`
            );

            debugLog(
                'UPDATE TABLE CHECK',
                hasLiveRequirementsPanel
                    ? (
                        `Live Mission Requirements panel detected. ` +
                        `Using ${liveRequirementsTables.length} live table(s) as the sole update source; ` +
                        `${Math.max(0, discoveredUpdateTables.length - liveRequirementsTables.length)} legacy table(s) ignored.`
                    )
                    : (
                        `No Live Mission Requirements panel detected. ` +
                        `Using ${updateTables.length} legacy update table(s) and alert fallbacks.`
                    )
            );

            if (
                hasLiveRequirementsPanel
            ) {
                debugLog(
                    'LIVE PANEL AUTHORITATIVE',
                    'Legacy general alerts and parent-page Missing Vehicles/Personnel text are ignored. Explicit patient alerts are fallback-only when the live panel has no confirmed row for that patient unit.'
                );
            }
        }

        const recordUpdateRequirement =
            (
                unitName,
                stillNeeded,
                source,
                details = null
            ) => {
                let cleanedName =
                    String(
                        unitName ||
                        ''
                    )
                        .replace(
                            /\s+/g,
                            ' '
                        )
                        .trim();

                const neededMatch =
                    String(
                        stillNeeded ??
                        ''
                    )
                        .replace(
                            /,/g,
                            ''
                        )
                        .match(
                            /\d+/
                        );

                let needed =
                    Math.max(
                        0,
                        neededMatch
                            ? parseInt(
                                neededMatch[0],
                                10
                            ) ||
                            0
                            : 0
                    );

                if (
                    !cleanedName ||
                    needed <=
                    0
                ) {
                    return;
                }

                if (shouldIgnoreRequiredMinimumRequirement(cleanedName)) {
                    return;
                }

                const towRequirement =
                    getCarsToTowVehicleRequirement(
                        cleanedName,
                        needed
                    );

                if (towRequirement) {
                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'UPDATE TOW CONVERSION',
                            `${towRequirement.carsRequired} car(s) to tow -> Flatbed Recovery Vehicle x${towRequirement.stillNeeded} | source=${source}`
                        );
                    }

                    cleanedName =
                        towRequirement.unitName;

                    needed =
                        towRequirement.stillNeeded;

                    details = {
                        ...(
                            details ||
                            {}
                        ),
                        towRequirement
                    };
                }

                const patientRequirement =
                    normaliseMissionUpdatePatientRequirement(
                        cleanedName,
                        needed
                    );

                if (
                    patientRequirement.type
                ) {
                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'UPDATE PATIENT RULE',
                            `${cleanedName} x${needed} -> ${patientRequirement.unitName} x${patientRequirement.stillNeeded}` +
                            `${patientRequirement.capped ? ' (capped at one)' : ' (required count preserved)'}` +
                            ` | source=${source}`
                        );
                    }

                    cleanedName =
                        patientRequirement.unitName;

                    needed =
                        patientRequirement.stillNeeded;
                }

                if (
                    needed <=
                    0
                ) {
                    return;
                }

                const sarPersonnelConversion =
                    getSarPersonnelVehicleRequirement(
                        cleanedName,
                        needed
                    );

                if (sarPersonnelConversion) {
                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'UPDATE SAR PERSONNEL',
                            `${sarPersonnelConversion.personnelRequirement} -> ${sarPersonnelConversion.unitName} x${sarPersonnelConversion.stillNeeded} (${sarPersonnelConversion.personnelPerVehicle} personnel per vehicle) | source=${source}`
                        );
                    }

                    cleanedName =
                        sarPersonnelConversion.unitName;

                    needed =
                        sarPersonnelConversion.stillNeeded;

                    details = {
                        ...(
                            details ||
                            {}
                        ),
                        sarPersonnelConversion
                    };
                }

                const publicOrderLevel =
                    getPublicOrderPersonnelLevel(
                        cleanedName
                    );

                if (
                    publicOrderLevel ===
                    1
                ) {
                    tableLevel1PublicOrderRequired =
                        Math.max(
                            tableLevel1PublicOrderRequired,
                            needed
                        );

                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'PUBLIC ORDER TABLE COLLAPSE',
                            `Level 1 x${needed} captured from ${source} for MAX calculation; not added as a vehicle row.`
                        );
                    }

                    return;
                }

                if (
                    publicOrderLevel ===
                    2
                ) {
                    tableLevel2PublicOrderRequired =
                        Math.max(
                            tableLevel2PublicOrderRequired,
                            needed
                        );

                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'PUBLIC ORDER TABLE COLLAPSE',
                            `Level 2 x${needed} captured from ${source} for MAX calculation; not added as a vehicle row.`
                        );
                    }

                    return;
                }

                if (
                    isPoliceSergeantPersonnelRequirementName(
                        cleanedName
                    )
                ) {
                    tablePoliceSergeantRequired =
                        Math.max(
                            tablePoliceSergeantRequired,
                            needed
                        );

                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'PUBLIC ORDER TABLE COLLAPSE',
                            `Police Sergeant x${needed} captured from ${source} for the L1/L2/Sergeant MAX calculation; not added as a normal vehicle row.`
                        );
                    }

                    return;
                }

                if (
                    isPoliceInspectorPersonnelRequirementName(
                        cleanedName
                    )
                ) {
                    tablePoliceInspectorRequired =
                        Math.max(
                            tablePoliceInspectorRequired,
                            needed
                        );

                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'POLICE INSPECTOR TABLE COLLAPSE',
                            `Police Inspector x${needed} captured from ${source}; selecting only exact IRVs live-verified with 2 police_inspector-trained personnel.`
                        );
                    }

                    return;
                }


                if (
                    isPoliceMedicPersonnelRequirementName(
                        cleanedName
                    )
                ) {
                    tablePoliceMedicRequired =
                        Math.max(
                            tablePoliceMedicRequired,
                            needed
                        );

                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'POLICE MEDIC TABLE COLLAPSE',
                            `Police Medic x${needed} captured from ${source}; selecting exact IRVs live-verified with 2 police_medic-trained personnel.`
                        );
                    }

                    return;
                }

                if (
                    isRailwayPolicePersonnelRequirementName(
                        cleanedName
                    )
                ) {
                    tableRailwayPoliceRequired =
                        Math.max(
                            tableRailwayPoliceRequired,
                            needed
                        );

                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'RAILWAY POLICE TABLE COLLAPSE',
                            `Railway Police Officer x${needed} captured from ${source}; selecting exact IRVs live-verified with 2 railway_police-trained personnel.`
                        );
                    }

                    return;
                }


                if (
                    isArmedResponsePersonnelRequirementName(
                        cleanedName
                    )
                ) {
                    tableArmedResponseRequired = Math.max(
                        tableArmedResponseRequired,
                        needed
                    );

                    if (mfDebugEnabled && !silent) {
                        debugLog(
                            'ARMED RESPONSE TABLE COLLAPSE',
                            `Armed Response Personnel x${needed} captured from ${source}; selecting exact type-25 ATCs with 2 officers who each hold traffic_police + swat.`
                        );
                    }

                    return;
                }

                missingRows.push({
                    unitName:
                        cleanedName,
                    stillNeeded:
                        needed,
                    updateSource:
                        source,
                    liveRequirementDetails:
                        details,
                    patientRequirementType:
                        patientRequirement.type || '',
                    isPatientAlertFallback:
                        false,
                    isTotalPatientRequirement:
                        false
                });
            };

        updateTables.forEach(table => {
            const liveRequirementsTable =
                isLiveMissionRequirementsTable(
                    table
                );

            table.querySelectorAll(
                'tbody tr'
            ).forEach(row => {
                if (
                    liveRequirementsTable
                ) {
                    const parsed =
                        readLiveMissionRequirementRow(
                            row
                        );

                    if (!parsed) {
                        return;
                    }

                    const liveDispatchTarget =
                        getLiveRequirementDispatchTarget(
                            parsed
                        );

                    const liveDispatchTargetMode =
                        parsed.stillNeededText &&
                        parsed.stillNeededText !== '?'
                            ? 'shortage'
                            : 'total';

                    if (
                        mfDebugEnabled &&
                        !silent
                    ) {
                        debugLog(
                            'LIVE REQUIREMENTS ROW',
                            `${parsed.unitName} | required=${parsed.requiredText || '?'} | ` +
                            `selected=${parsed.selectedText || '?'} | ` +
                            `still=${parsed.stillNeededText || '?'} | ` +
                            `state=${parsed.rowState || 'none'} | ` +
                            `confirmation=${parsed.requiresConfirmation ? 'yes' : 'no'} | ` +
                            `using-update-target=${liveDispatchTarget} | ` +
                            `target-mode=${liveDispatchTargetMode} | ` +
                            `panel-still=${parsed.stillNeeded}`
                        );
                    }

                    const livePatientRule =
                        getMissionUpdatePatientRequirementRule(
                            parsed.unitName
                        );

                    if (livePatientRule) {
                        const explicitNeed =
                            parseMissionRequirementNumber(
                                parsed.stillNeededText
                            );

                        const requiredValue =
                            parseMissionRequirementNumber(
                                parsed.requiredText
                            );

                        const selectedValue =
                            parseMissionRequirementNumber(
                                parsed.selectedText
                            );

                        const isConfirmed =
                            !parsed.requiresConfirmation &&
                            (
                                explicitNeed !== null ||
                                (
                                    requiredValue !== null &&
                                    selectedValue !== null
                                )
                            );

                        if (isConfirmed) {
                            const existingState =
                                livePatientRequirementStates.get(
                                    livePatientRule.type
                                );

                            const confirmedNeed =
                                Math.max(
                                    0,
                                    parseInt(
                                        parsed.stillNeeded,
                                        10
                                    ) || 0
                                );

                            livePatientRequirementStates.set(
                                livePatientRule.type,
                                {
                                    type:
                                        livePatientRule.type,
                                    unitName:
                                        livePatientRule.unitName,
                                    stillNeeded:
                                        Math.max(
                                            existingState?.stillNeeded || 0,
                                            confirmedNeed
                                        ),
                                    sources:
                                        (existingState?.sources || 0) + 1
                                }
                            );

                            if (
                                mfDebugEnabled &&
                                !silent
                            ) {
                                debugLog(
                                    'LIVE PATIENT AUTHORITY',
                                    `${livePatientRule.unitName} confirmed by live panel | need=${confirmedNeed} | patient alerts for this unit will be ignored`
                                );
                            }
                        }
                    }

                    recordUpdateRequirement(
                        parsed.unitName,
                        liveDispatchTarget,
                        'live-requirements-panel',
                        {
                            ...parsed,
                            dispatchTarget:
                                liveDispatchTarget,
                            dispatchTargetSource:
                                liveDispatchTargetMode === 'shortage'
                                    ? 'reported-still-needed'
                                    : 'required-fallback-for-unknown',
                            dispatchTargetMode:
                                liveDispatchTargetMode
                        }
                    );

                    return;
                }

                const cells =
                    row.querySelectorAll(
                        'td'
                    );

                if (
                    cells.length <
                    4
                ) {
                    return;
                }

                const unitName =
                    (
                        cells[0].innerText ||
                        cells[0].textContent ||
                        ''
                    )
                        .replace(
                            /\s+/g,
                            ' '
                        )
                        .trim();

                const cellTexts =
                    Array.from(
                        cells
                    ).map(cell => {
                        return (
                            cell.innerText ||
                            cell.textContent ||
                            ''
                        )
                            .replace(
                                /\s+/g,
                                ' '
                            )
                            .trim();
                    });

                const preferredText =
                    cellTexts[3] ||
                    '';

                let stillNeeded =
                    parseInt(
                        preferredText,
                        10
                    );

                if (
                    !Number.isFinite(
                        stillNeeded
                    ) ||
                    stillNeeded <=
                    0
                ) {
                    const numericCells =
                        cellTexts
                            .map(value => {
                                return parseInt(
                                    value,
                                    10
                                );
                            })
                            .filter(value => {
                                return (
                                    Number.isFinite(
                                        value
                                    ) &&
                                    value >
                                    0
                                );
                            });

                    stillNeeded =
                        numericCells.length
                            ? numericCells[
                                numericCells.length -
                                1
                            ]
                            : 0;
                }

                recordUpdateRequirement(
                    unitName,
                    stillNeeded,
                    'legacy-update-table'
                );
            });
        });

        // Read exact visible problem alerts from the active mission only.
        // Parent containers and hidden/previous missions are deliberately
        // excluded to prevent unrelated vehicle selections.
        const pageTextBlocks =
            hasLiveRequirementsPanel
                ? []
                : getActiveMissionProblemTextBlocks(
                    missionUpdateRoots
                );

        if (
            mfDebugEnabled &&
            !silent
        ) {
            debugLog(
                'UPDATE ALERT CHECK',
                hasLiveRequirementsPanel
                    ? 'Skipped legacy update alert scan because the Live Mission Requirements panel is authoritative.'
                    : pageTextBlocks.length
                    ? (
                        `Found ${pageTextBlocks.length} visible update alert block(s): ` +
                        pageTextBlocks
                            .map(
                                (
                                    value,
                                    index
                                ) =>
                                    `${index + 1}="${value.slice(0, 300)}"`
                            )
                            .join(' || ')
                    )
                    : `Found 0 visible update alert blocks across ${missionUpdateRoots.length} root(s).`
            );

            if (
                mfHighDebugEnabled &&
                !hasLiveRequirementsPanel &&
                pageTextBlocks.length ===
                    0
            ) {
                const bodyMatches =
                    getMissionAccessibleDocuments()
                        .filter(
                            candidateDocument => {
                                try {
                                    return /Missing\s+(?:Vehicles?|Personnel):/i
                                        .test(
                                            candidateDocument
                                                .body
                                                ?.textContent ||
                                            ''
                                        );
                                } catch (_error) {
                                    return false;
                                }
                            }
                        )
                        .map(
                            candidateDocument =>
                                candidateDocument.URL ||
                                'unknown'
                        );

                debugLog(
                    'UPDATE BODY PROBE',
                    bodyMatches.length
                        ? `The phrase exists in document text but no visible alert element was accepted: ${bodyMatches.join(' | ')}`
                        : 'No accessible document body contains Missing Vehicles/Personnel text.'
                );
            }
        }

        pageTextBlocks.forEach(text => {
            if (!/Missing Vehicles?:/i.test(text)) return;

            getGenericMissingVehicleRowsFromText(
                text
            ).forEach(row => {
                missingRows.push(
                    row
                );

                if (
                    mfDebugEnabled &&
                    !silent
                ) {
                    debugLog(
                        'UPDATE GENERIC VEHICLE',
                        `${row.unitName} x${row.stillNeeded}`
                    );
                }
            });

            const lowerText = text.toLowerCase();

            const carToTowMatch = lowerText.match(
                /(\d+)\s+car(?:s)?\s+to\s+tow/
            );

            if (carToTowMatch) {
                const amount = parseInt(
                    carToTowMatch[1],
                    10
                );

                if (
                    Number.isFinite(amount) &&
                    amount > 0
                ) {
                    const towRequirement =
                        getCarsToTowVehicleRequirement(
                            'Cars to tow',
                            amount
                        );

                    if (towRequirement) {
                        missingRows.push({
                            unitName:
                                towRequirement.unitName,
                            stillNeeded:
                                towRequirement.stillNeeded,
                            towCarsRequired:
                                towRequirement.carsRequired
                        });
                    }
                }
            }

            // MissionChief can expose Police Air only in the red
            // Missing Vehicles alert rather than the update table.
            // Convert it to a normal update row. The existing strict
            // Police Air matcher then prefers Drone Vehicle
            // (Police Station), with Police Helicopter as fallback.
            const policeAirMatches = Array.from(
                text.matchAll(
                    /(\d+)\s*(?:x\s*)?Police\s+Helicopter(?:s)?\s+or\s+Drone(?:s)?/gi
                )
            );

            policeAirMatches.forEach(match => {
                const amount =
                    parseInt(
                        match[1],
                        10
                    );

                if (
                    !Number.isFinite(amount) ||
                    amount <= 0
                ) {
                    return;
                }

                missingRows.push({
                    unitName:
                        'Police Helicopter or Drone',
                    stillNeeded:
                        amount
                });

                if (
                    mfDebugEnabled &&
                    !silent
                ) {
                    debugLog(
                        'UPDATE POLICE AIR',
                        `Missing Vehicles text -> Drone Vehicle (Police Station) first, Police Helicopter fallback x${amount}`
                    );
                }
            });

            // MissionChief can place this requirement only inside the
            // red Missing Vehicles alert rather than the update table.
            // Convert it to the normal selector row so Update ticks ALB.
            const seagoingMatches = Array.from(
                text.matchAll(
                    /(\d+)\s*(?:x\s*)?Seagoing\s+Vessel(?:s)?/gi
                )
            );

            seagoingMatches.forEach(match => {
                const amount = parseInt(
                    match[1],
                    10
                );

                if (
                    !Number.isFinite(amount) ||
                    amount <= 0
                ) {
                    return;
                }

                missingRows.push({
                    unitName: 'Seagoing Vessel',
                    stillNeeded: amount
                });

                if (mfDebugEnabled && !silent) {
                    debugLog(
                        'UPDATE SEAGOING',
                        `Missing Vehicles text -> ALB x${amount}`
                    );
                }
            });
        });

        // Missing Personnel is an actionable mission update, not a
        // vehicle staffing fault. Supported personnel conversions include:
        // Search Technicians = 4 per displayed-name-prefix SARTEC vehicle
        // Search Advisors = 2 per displayed-name-prefix SARTEC vehicle
        // SAR Commanders = 2 per Control Van
        // 3 Police Officers = 2 Police Cars
        // 6 Mud Rescue Operators = 2 Coastguard Mud Rescue Units
        // Normal update-table vehicle requirements are selected as well.
        let maximumSartecUnitsFromPersonnel = 0;

        const trainedPersonnelRequirements =
            new Map();

        if (
            tableLevel1PublicOrderRequired >
                0 ||
            tableLevel2PublicOrderRequired >
                0 ||
            tablePoliceSergeantRequired >
                0 ||
            tablePoliceInspectorRequired >
                0 ||
            tablePoliceMedicRequired >
                0 ||
            tableRailwayPoliceRequired >
                0 ||
            tableArmedResponseRequired >
                0
        ) {
            mergeTrainedPersonnelRequirements(
                trainedPersonnelRequirements,
                normalisePublicOrderTrainedRequirements([
                    {
                        code:
                            'level_1_public_order',
                        label:
                            'Level 1 Public Order Officer',
                        required:
                            tableLevel1PublicOrderRequired
                    },
                    {
                        code:
                            'level_2_public_order',
                        label:
                            'Level 2 Public Order Officer',
                        required:
                            tableLevel2PublicOrderRequired
                    },
                    {
                        code:
                            'police_sergeant',
                        label:
                            'Police Sergeant',
                        required:
                            tablePoliceSergeantRequired
                    },
                    {
                        code:
                            'police_inspector',
                        label:
                            'Police Inspector',
                        required:
                            tablePoliceInspectorRequired
                    },
                    {
                        code:
                            'police_medic',
                        label:
                            'Police Medic',
                        required:
                            tablePoliceMedicRequired
                    },
                    {
                        code:
                            'railway_police',
                        label:
                            'Railway Police Officer',
                        required:
                            tableRailwayPoliceRequired
                    },
                    {
                        code:
                            'armed_response_personnel',
                        label:
                            'Armed Response Personnel',
                        required:
                            tableArmedResponseRequired
                    }
                ])
            );
        }

        pageTextBlocks.forEach(text => {
            if (!/Missing Personnel:/i.test(text)) return;

            mergeTrainedPersonnelRequirements(
                trainedPersonnelRequirements,
                getSupportedTrainedPersonnelRequirementsFromText(
                    text
                )
            );

            const personnelRows =
                getSupportedMissingPersonnelRowsFromText(
                    text,
                    { silent }
                );

            personnelRows.forEach(row => {
                if (
                    normaliseVehicleText(
                        row.unitName
                    ) === 'sartec'
                ) {
                    maximumSartecUnitsFromPersonnel =
                        Math.max(
                            maximumSartecUnitsFromPersonnel,
                            parseInt(
                                row.stillNeeded,
                                10
                            ) || 0
                        );

                    return;
                }

                missingRows.push({
                    unitName: row.unitName,
                    stillNeeded: row.stillNeeded
                });
            });
        });

        if (
            maximumSartecUnitsFromPersonnel > 0
        ) {
            missingRows.push({
                unitName: 'SARTEC',
                stillNeeded:
                    maximumSartecUnitsFromPersonnel
            });
        }

        if (
            trainedPersonnelRequirements.size >
            0
        ) {
            const requirements =
                Array.from(
                    trainedPersonnelRequirements
                        .values()
                );

            missingRows.push({
                unitName:
                    MF_TRAINED_PERSONNEL_ROW_NAME,
                stillNeeded:
                    getTrainedPersonnelVehicleTarget(
                        requirements
                    ),
                isTrainedPersonnelRequirement:
                    true,
                personnelTrainingRequirements:
                    requirements
            });

            if (
                mfDebugEnabled &&
                !silent
            ) {
                debugLog(
                    'TRAINED PERSONNEL UPDATE',
                    formatTrainedPersonnelRequirements(
                        requirements
                    )
                );
            }
        }

        // Dynamic patient update reader.
        // Reads the individual items after "We need:" rather than comparing
        // the whole sentence. This keeps combined requests working.
        const patientAlertRoots =
            hasLiveRequirementsPanel
                ? getCurrentMissionPatientAlertRoots(
                    liveRequirementsTables,
                    missionUpdateRoots
                )
                : missionUpdateRoots;

        const patientAlertCandidates =
            Array.from(
                new Set(
                    patientAlertRoots
                        .flatMap(root => {
                            try {
                                return Array.from(
                                    root.querySelectorAll(
                                        '.mission_patient .alert.alert-danger, ' +
                                        '.alert.alert-danger[id^="patients_missing_"], ' +
                                        '[id^="patients_missing_"].alert-danger'
                                    )
                                );
                            } catch (_error) {
                                return [];
                            }
                        })
                )
            );

        const visibleCurrentPatientBadgeCount =
            getVisiblePatientBadgeCountInRoots(
                patientAlertRoots
            );

        const patientAlerts =
            patientAlertCandidates.filter(
                element =>
                    isCurrentMissionPatientAlert(
                        element,
                        patientAlertRoots,
                        hasLiveRequirementsPanel,
                        visibleCurrentPatientBadgeCount
                    )
            );

        if (
            hasLiveRequirementsPanel &&
            mfDebugEnabled &&
            !silent
        ) {
            debugLog(
                'PATIENT ALERT SCOPE GUARD',
                `roots=${patientAlertRoots.length} | candidates=${patientAlertCandidates.length} | accepted=${patientAlerts.length} | rejected=${Math.max(0, patientAlertCandidates.length - patientAlerts.length)} | patientBadge=${visibleCurrentPatientBadgeCount}`
            );
        }

        if (
            hasLiveRequirementsPanel &&
            mfDebugEnabled &&
            !silent
        ) {
            debugLog(
                'PATIENT ALERT SOURCE',
                'Live Mission Requirements remains authoritative for general update rows. Explicit patient We need alerts are read separately, then capped and deduplicated against the panel.'
            );
        }

        let ambulanceRequired = 0;
        let criticalCareRequired = 0;
        let needsAmbulanceOfficer = false;
        let needsMassCasualtyEquipment = false;

        const patientGroups =
            new Map();

        patientAlerts.forEach(
            (
                element,
                alertIndex
            ) => {
                const originalText =
                    normaliseMissionAlertText(
                        element.textContent ||
                        element.innerText ||
                        ''
                    );

                const lowerText =
                    originalText
                        .toLowerCase();

                const needIndex =
                    lowerText.indexOf(
                        'we need:'
                    );

                if (
                    needIndex ===
                    -1
                ) {
                    return;
                }

                const prefix =
                    lowerText.slice(
                        0,
                        needIndex
                    );

                const multiplierMatch =
                    prefix.match(
                        /(\d+)\s*x\s*$/
                    );

                const multiplier =
                    multiplierMatch
                        ? Math.max(
                            1,
                            parseInt(
                                multiplierMatch[1],
                                10
                            ) ||
                            1
                        )
                        : 1;

                const requirementText =
                    lowerText
                        .slice(
                            needIndex +
                            'we need:'.length
                        )
                        .trim();

                const requirements =
                    requirementText
                        .split(/,|;|\s+and\s+/i)
                        .map(value => {
                            return value
                                .replace(
                                    /[.!;]+$/g,
                                    ''
                                )
                                .replace(
                                    /\s+/g,
                                    ' '
                                )
                                .trim();
                        })
                        .filter(Boolean);

                const groupKey =
                    getPatientAlertGroupKey(
                        element,
                        alertIndex
                    );

                let group =
                    patientGroups.get(
                        groupKey
                    );

                if (!group) {
                    group = {
                        key:
                            groupKey,
                        multiplier:
                            1,
                        hasAmbulance:
                            false,
                        hasCriticalCare:
                            false,
                        hasAmbulanceOfficer:
                            false,
                        hasMassCasualtyEquipment:
                            false,
                        hasLinkedVisiblePatient:
                            false,
                        sourceTexts:
                            new Set()
                    };

                    patientGroups.set(
                        groupKey,
                        group
                    );
                }

                group.multiplier =
                    Math.max(
                        group.multiplier,
                        multiplier
                    );

                group.hasLinkedVisiblePatient =
                    group.hasLinkedVisiblePatient ||
                    !!getLinkedVisiblePatientContainer(
                        element,
                        patientAlertRoots
                    );

                group.hasAmbulance =
                    group.hasAmbulance ||
                    requirements.some(
                        value =>
                            value ===
                            'ambulance'
                    );

                group.hasCriticalCare =
                    group.hasCriticalCare ||
                    requirements.some(
                        value =>
                            value ===
                                'critical care' ||
                            value ===
                                'critical care team'
                    );

                group.hasAmbulanceOfficer =
                    group.hasAmbulanceOfficer ||
                    requirements.some(
                        value =>
                            value ===
                                'ambulance officer' ||
                            value ===
                                'ambulance officers'
                    );

                group.hasMassCasualtyEquipment =
                    group
                        .hasMassCasualtyEquipment ||
                    requirements.some(
                        value =>
                            value ===
                                'mass casualty equipment' ||
                            value ===
                                'mass casualty equipment unit'
                    );

                group.sourceTexts.add(
                    originalText
                );
            }
        );

        const isPatientAlertOwnedByLivePanel =
            (type, group) =>
                livePatientRequirementStates.has(
                    type
                ) &&
                !group?.hasLinkedVisiblePatient;

        patientGroups
            .forEach(group => {
                // V10.6.60: MissionChief can show a single patient request as
                // "We need: Critical Care, Ambulance". This is one transport
                // requirement, not two separate vehicles. The normal Ambulance
                // carries the patient, so suppress Critical Care transport only
                // for a patient group that requests both. A Critical Care-only
                // patient still selects the required Critical Care vehicle(s).
                const ambulanceReplacesCriticalCareTransport =
                    group.hasAmbulance &&
                    group.hasCriticalCare;

                if (
                    group.hasAmbulance &&
                    !isPatientAlertOwnedByLivePanel(
                        'ambulance',
                        group
                    )
                ) {
                    ambulanceRequired +=
                        group.multiplier;
                }

                if (
                    group.hasCriticalCare &&
                    !ambulanceReplacesCriticalCareTransport &&
                    !isPatientAlertOwnedByLivePanel(
                        'critical-care',
                        group
                    )
                ) {
                    criticalCareRequired +=
                        group.multiplier;
                }

                if (
                    group
                        .hasAmbulanceOfficer &&
                    !isPatientAlertOwnedByLivePanel(
                        'ambulance-officer',
                        group
                    )
                ) {
                    needsAmbulanceOfficer =
                        true;
                }

                if (
                    group
                        .hasMassCasualtyEquipment &&
                    !isPatientAlertOwnedByLivePanel(
                        'mass-casualty-equipment',
                        group
                    )
                ) {
                    needsMassCasualtyEquipment =
                        true;
                }

                if (
                    mfDebugEnabled &&
                    !silent
                ) {
                    debugLog(
                        'PATIENT GROUP',
                        `${group.key} | alerts=${Array.from(group.sourceTexts).join(' + ')} | ` +
                        `Ambulance=${group.hasAmbulance ? (isPatientAlertOwnedByLivePanel('ambulance', group) ? 'ignored/live-panel-owned' : `x${group.multiplier}`) : 'no'} | ` +
                        `Critical Care=${group.hasCriticalCare ? (ambulanceReplacesCriticalCareTransport ? 'suppressed/ambulance-is-transport' : (isPatientAlertOwnedByLivePanel('critical-care', group) ? 'ignored/live-panel-owned' : `x${group.multiplier}`)) : 'no'} | ` +
                        `Officer=${group.hasAmbulanceOfficer ? (isPatientAlertOwnedByLivePanel('ambulance-officer', group) ? 'ignored/live-panel-owned' : 'yes/capped at 1') : 'no'} | ` +
                        `MCE=${group.hasMassCasualtyEquipment ? (isPatientAlertOwnedByLivePanel('mass-casualty-equipment', group) ? 'ignored/live-panel-owned' : 'yes/capped at 1') : 'no'}`
                    );
                }
            });

        // Patient alerts describe the total current patient demand. Some
        // MissionChief layouts repeat a "2x We need: Ambulance" message on
        // each of two patient cards, which previously produced 4 Ambulances.
        // Cap scalable patient units to the current visible patient total.
        const currentPatientTotal =
            visibleCurrentPatientBadgeCount > 0
                ? visibleCurrentPatientBadgeCount
                : findPatientCount(true);

        if (currentPatientTotal > 0) {
            ambulanceRequired =
                Math.min(
                    ambulanceRequired,
                    currentPatientTotal
                );

            criticalCareRequired =
                Math.min(
                    criticalCareRequired,
                    currentPatientTotal
                );
        }

        if (ambulanceRequired > 0) {
            missingRows.push({
                unitName: 'Ambulance x 01',
                stillNeeded: ambulanceRequired,
                patientRequirementType: 'ambulance',
                isPatientAlertFallback: true,
                isTotalPatientRequirement: true,
                patientCountCap: currentPatientTotal
            });
        }

        if (criticalCareRequired > 0) {
            missingRows.push({
                unitName: 'Critical Care',
                stillNeeded: criticalCareRequired,
                patientRequirementType: 'critical-care',
                isPatientAlertFallback: true,
                isTotalPatientRequirement: true,
                patientCountCap: currentPatientTotal
            });

            if (mfDebugEnabled && !silent) {
                debugLog(
                    'PATIENT CRITICAL CARE',
                    `Patient alerts require Critical Care x${criticalCareRequired}`
                );
            }
        }

        // Ambulance Officer is capped at one unit total, even when
        // several patients or a multiplier request it.
        if (needsAmbulanceOfficer) {
            missingRows.push({
                unitName: 'Ambulance Officer',
                stillNeeded: 1,
                patientRequirementType: 'ambulance-officer',
                isPatientAlertFallback: true,
                isTotalPatientRequirement: true,
                patientCountCap: currentPatientTotal
            });
        }

        // Mass Casualty Equipment remains capped at one unit total,
        // regardless of how many patient alerts request it.
        if (needsMassCasualtyEquipment) {
            missingRows.push({
                unitName: 'Mass Casualty Equipment',
                stillNeeded: 1,
                patientRequirementType: 'mass-casualty-equipment',
                isPatientAlertFallback: true,
                isTotalPatientRequirement: true,
                patientCountCap: currentPatientTotal
            });

            if (mfDebugEnabled && !silent) {
                debugLog(
                    'PATIENT MCE',
                    'Patient requires Mass Casualty Equipment -> select Mass Casualty Equipment x1'
                );
            }
        }

        // De-duplicate requirements. MissionChief can expose the same
        // red alert through several nested elements, so retain the maximum
        // amount for each mapped vehicle requirement.
        const dedupedByMappedName =
            new Map();

        missingRows.forEach(row => {
            if (
                row
                    .isTrainedPersonnelRequirement
            ) {
                const signature =
                    getTrainedPersonnelRequirementsSignature(
                        row.personnelTrainingRequirements
                    );

                if (!signature) {
                    return;
                }

                dedupedByMappedName.set(
                    `trained-personnel:${signature}`,
                    {
                        ...row,
                        stillNeeded:
                            getTrainedPersonnelVehicleTarget(
                                row
                                    .personnelTrainingRequirements
                            )
                    }
                );

                return;
            }

            const patientRequirement =
                normaliseMissionUpdatePatientRequirement(
                    row.unitName,
                    row.stillNeeded
                );

            const effectiveUnitName =
                patientRequirement.unitName ||
                row.unitName;

            const mappedName =
                resolveUnitName(
                    effectiveUnitName
                );

            const canonicalName =
                normaliseVehicleText(
                    mappedName ||
                    effectiveUnitName
                );

            const amount =
                patientRequirement.stillNeeded;

            if (
                !canonicalName ||
                amount <= 0
            ) {
                return;
            }

            const existing =
                dedupedByMappedName.get(
                    canonicalName
                );

            if (
                !existing ||
                amount >
                    existing.stillNeeded
            ) {
                dedupedByMappedName.set(
                    canonicalName,
                    {
                        ...row,
                        unitName:
                            effectiveUnitName,
                        stillNeeded:
                            amount,
                        patientRequirementType:
                            row.patientRequirementType ||
                            patientRequirement.type ||
                            '',
                        isPatientAlertFallback:
                            !!row.isPatientAlertFallback,
                        isTotalPatientRequirement:
                            !!row.isTotalPatientRequirement
                    }
                );
            }
        });

        const deduped =
            Array.from(
                dedupedByMappedName.values()
            ).sort(
                (
                    left,
                    right
                ) => {
                    const leftPriority =
                        left
                            .isTrainedPersonnelRequirement
                            ? 0
                            : 1;

                    const rightPriority =
                        right
                            .isTrainedPersonnelRequirement
                            ? 0
                            : 1;

                    return (
                        leftPriority -
                        rightPriority
                    );
                }
            );

        if (
            mfDebugEnabled &&
            !silent &&
            deduped.length >
                0
        ) {
            debugLog(
                'UPDATE ORDER',
                deduped
                    .map(row => {
                        return row
                            .isTrainedPersonnelRequirement
                                ? `TRAINED:${formatTrainedPersonnelRequirements(row.personnelTrainingRequirements)}`
                                : `GENERAL:${row.unitName} x${row.stillNeeded}`;
                    })
                    .join(' -> ')
            );
        }

        if (mfDebugEnabled && !silent) {
            debugLog(
                'UPDATE ROWS',
                deduped.length
                    ? deduped.map(row => {
                        return row.isTrainedPersonnelRequirement
                            ? `${row.unitName}: ${formatTrainedPersonnelRequirements(row.personnelTrainingRequirements)}`
                            : `${row.unitName} x${row.stillNeeded}`;
                    }).join(' | ')
                    : 'None'
            );
        }

        mfMissionUpdateRowsCache = {
            expiresAt: Date.now() + 175,
            missionKey,
            rows: deduped
        };

        return deduped;
    }

    function getMissionUpdateFirstPassKey() {
        const missionId = getCurrentMissionIdForQueueRestart();

        if (missionId) {
            return `mission-${missionId}`;
        }

        const helpLink =
            getActiveMissionHelpLink();

        const helpHref = helpLink
            ? (
                helpLink.getAttribute(
                    'href'
                ) ||
                helpLink.href ||
                ''
            )
            : '';

        if (helpHref) {
            return `help-${helpHref}`;
        }

        const missionName = getCurrentMissionName();

        return missionName
            ? `name-${missionName}`
            : 'mission-unknown';
    }

    function getMissionUpdateRenderSignature() {
        const roots =
            Array.from(
                new Set(
                    getActiveMissionRequirementContexts()
                        .map(
                            context =>
                                context.root
                        )
                )
            );

        const updateTables =
            Array.from(
                new Set(
                    roots.flatMap(root => {
                        try {
                            return Array.from(
                                root.querySelectorAll(
                                    '#mc-map-command-toolkit-mission-requirements[data-mcms-requirements-panel="1"] table[aria-label="Live mission requirements"], ' +
                                        'section[data-mcms-requirements-panel="1"] table[aria-label="Live mission requirements"], ' +
                                        'table.table-striped.table-condensed, table.table'
                                )
                            );
                        } catch (_error) {
                            return [];
                        }
                    })
                )
            )
                .filter(
                    isMissionUpdateTable
                )
                .filter(
                    table =>
                        isMissionElementVisible(
                            table
                        )
                );

        const updateTableText =
            updateTables
                .map(table => (
                    table.innerText ||
                    table.textContent ||
                    ''
                )
                    .replace(
                        /\s+/g,
                        ' '
                    )
                    .trim()
                )
                .join(' || ')
                .slice(
                    0,
                    1200
                );

        const patientAlerts =
            Array.from(
                new Set(
                    roots.flatMap(root => {
                        try {
                            return Array.from(
                                root.querySelectorAll(
                                    '.mission_patient .alert.alert-danger'
                                )
                            );
                        } catch (_error) {
                            return [];
                        }
                    })
                )
            )
                .filter(
                    alert =>
                        isMissionElementVisible(
                            alert
                        )
                )
                .map(alert => (
                    alert.innerText ||
                    alert.textContent ||
                    ''
                )
                    .replace(
                        /\s+/g,
                        ' '
                    )
                    .trim()
                )
                .join(' || ')
                .slice(
                    0,
                    800
                );

        const visibleProblemAlerts =
            getActiveMissionProblemTextBlocks(
                roots
            )
                .join(' || ')
                .slice(
                    0,
                    1200
                );

        const vehicleCount =
            roots.reduce(
                (
                    total,
                    root
                ) => {
                    try {
                        return (
                            total +
                            root
                                .querySelectorAll(
                                    'a[search_attribute], input[type="checkbox"][vehicle_id], input[type="checkbox"][id^="vehicle_"]'
                                )
                                .length
                        );
                    } catch (_error) {
                        return total;
                    }
                },
                0
            );

        const dispatchPresent =
            roots.some(root => {
                try {
                    return !!root.querySelector(
                        '#alarm_button, #mission_alarm_btn, input[type="submit"][name="commit"], button[type="submit"]'
                    );
                } catch (_error) {
                    return false;
                }
            });

        return [
            updateTables.length,
            updateTableText,
            patientAlerts,
            visibleProblemAlerts,
            vehicleCount,
            dispatchPresent
                ? 1
                : 0
        ].join('|');
    }

    function requireMissionUpdateFirstPass(reason) {
        mfMissionUpdateFirstPassRequired = true;
        mfMissionUpdateFirstPassCompletedAt = 0;

        if (mfDebugEnabled) {
            debugLog(
                'UPDATE FIRST GATE',
                `Required again | reason=${reason || 'unknown'}`
            );
        }
    }

    async function waitForMissionUpdateBeforeUnitFinder(reason) {
        const initialKey = getMissionUpdateFirstPassKey();

        if (
            initialKey &&
            initialKey !== mfMissionUpdateFirstPassMissionKey
        ) {
            mfMissionUpdateFirstPassMissionKey = initialKey;
            mfMissionUpdateFirstPassRequired = true;
            mfMissionUpdateFirstPassCompletedAt = 0;
        }

        if (!mfMissionUpdateFirstPassRequired) {
            return readMissionUpdateRows({ silent: true });
        }

        updateStatusBox(
            'Waiting for mission update data before Unit Finder...'
        );

        if (mfDebugEnabled) {
            debugLog(
                'UPDATE FIRST GATE',
                `Started | reason=${reason || 'unknown'} | mission=${initialKey || 'unknown'}`
            );
        }

        let gateStartedAt = Date.now();
        let basicReadyAt = 0;
        let lastSignature = '';
        let signatureStableAt = 0;
        let lastRowsSignature = '';
        let rowsStableAt = 0;
        let latestRows = [];

        while (
            Date.now() - gateStartedAt <
            MF_UPDATE_FIRST_MAX_WAIT_MS
        ) {
            if (
                isManualAutoStopActive() ||
                !autoModeRunning
            ) {
                return [];
            }

            if (!isMissionPage()) {
                await wait(300);
                continue;
            }

            const currentKey = getMissionUpdateFirstPassKey();

            if (
                currentKey &&
                currentKey !== mfMissionUpdateFirstPassMissionKey
            ) {
                mfMissionUpdateFirstPassMissionKey = currentKey;
                gateStartedAt = Date.now();
                basicReadyAt = 0;
                lastSignature = '';
                signatureStableAt = 0;
                lastRowsSignature = '';
                rowsStableAt = 0;
                latestRows = [];

                if (mfDebugEnabled) {
                    debugLog(
                        'UPDATE FIRST GATE',
                        `Mission identity changed while loading -> ${currentKey}`
                    );
                }
            }

            const hasMissionInfo =
                !!document.querySelector('#mission_general_info');

            const hasMissionHelp =
                !!document.querySelector('#mission_help');

            const hasVehicleInterface =
                !!document.querySelector(
                    'a[search_attribute], input[type="checkbox"][vehicle_id], input[type="checkbox"][id^="vehicle_"]'
                );

            if (
                hasMissionInfo &&
                hasMissionHelp &&
                hasVehicleInterface
            ) {
                if (!basicReadyAt) {
                    basicReadyAt = Date.now();
                }
            } else {
                basicReadyAt = 0;
            }

            const signature = getMissionUpdateRenderSignature();

            if (signature !== lastSignature) {
                lastSignature = signature;
                signatureStableAt = Date.now();
            }

            latestRows = readMissionUpdateRows({
                silent: true
            });

            const rowsSignature =
                getMissionUpdateRowsSignature(
                    latestRows
                );

            if (rowsSignature !== lastRowsSignature) {
                lastRowsSignature = rowsSignature;
                rowsStableAt = Date.now();
            }

            if (
                latestRows.length > 0 &&
                Date.now() - rowsStableAt >=
                    MF_UPDATE_FIRST_STABLE_MS
            ) {
                mfMissionUpdateFirstPassRequired = false;
                mfMissionUpdateFirstPassCompletedAt = Date.now();

                updateStatusBox(
                    `Mission update detected before Unit Finder (${latestRows.length} row(s)).`
                );

                if (mfDebugEnabled) {
                    debugLog(
                        'UPDATE FIRST GATE',
                        `Update route released after ${Date.now() - gateStartedAt}ms: ${latestRows.map(row => `${row.unitName} x${row.stillNeeded}`).join(', ')}`
                    );
                }

                return latestRows;
            }

            if (
                basicReadyAt &&
                Date.now() - basicReadyAt >=
                    MF_UPDATE_FIRST_MIN_WAIT_MS &&
                Date.now() - signatureStableAt >=
                    MF_UPDATE_FIRST_STABLE_MS
            ) {
                mfMissionUpdateFirstPassRequired = false;
                mfMissionUpdateFirstPassCompletedAt = Date.now();

                if (mfDebugEnabled) {
                    debugLog(
                        'UPDATE FIRST GATE',
                        `Normal Unit Finder route released after ${Date.now() - gateStartedAt}ms gate time; no update rows appeared.`
                    );
                }

                return [];
            }

            await wait(150);
        }

        latestRows = readMissionUpdateRows({
            silent: true
        });

        mfMissionUpdateFirstPassRequired = false;
        mfMissionUpdateFirstPassCompletedAt = Date.now();

        if (mfDebugEnabled) {
            debugLog(
                'UPDATE FIRST GATE',
                `Timed out after ${MF_UPDATE_FIRST_MAX_WAIT_MS}ms | rows=${latestRows.length}. Unit Finder permitted only after final update check.`
            );
        }

        return latestRows;
    }


    function handleMissionUpdateUnits(showAlerts, suppliedRows = null, options = {}) {
        if (!isCurrentMissionExecutionOwner('Mission Update')) {
            return false;
        }

        synchroniseMissionInstanceState('Mission Update start');

        updateStatusBox("Checking mission update requirements...");

        if (
            detectAndLatchStaffingBlock(
                'before-mission-update-selection'
            )
        ) {
            updateStatusBox(
                'Mission update is a staffing/qualification shortage. No extra vehicles selected.'
            );
            changeDispatchBoxColor(false);
            return false;
        }

        const rawMissingRows =
            Array.isArray(
                suppliedRows
            )
                ? suppliedRows
                : readMissionUpdateRows();

        // Supplied live-table rows can bypass readMissionUpdateRows(), so run
        // the same personnel-to-vehicle conversion at the Upgrade entry point.
        // This restores SAR Commander -> Control Van parity with Unit Finder.
        const missingRows =
            normaliseOperationalRequirementRows(
                rawMissingRows
            );

        if (mfDebugEnabled) {
            debugLog(
                'UPDATE ONLY',
                missingRows.length
                    ? `Active mission rows only: ${missingRows.map(row => `${row.unitName} x${row.stillNeeded}`).join(', ')}`
                    : 'No visible active-mission update rows found. Hidden and previous mission requirements were ignored.'
            );
        }

        if (missingRows.length === 0) {
            updateStatusBox("No mission update units needed.");
            return false;
        }

        const missingAfterAttempt = [];

        missingRows.forEach(item => {
            if (
                isPublicOrderPersonnelRequirementName(
                    item?.unitName
                )
            ) {
                if (
                    mfDebugEnabled
                ) {
                    debugLog(
                        'PUBLIC ORDER UPDATE GUARD',
                        `${item.unitName} skipped as a standalone row; the independent trained IRV requirements own it.`
                    );
                }

                return;
            }

            if (
                item
                    .isTrainedPersonnelRequirement
            ) {
                if (
                    mfDebugEnabled
                ) {
                    debugLog(
                        'TRAINED UPDATE ROUTE',
                        `Entering independent trained-vehicle selector for ${formatTrainedPersonnelRequirements(item.personnelTrainingRequirements)}`
                    );
                }

                const requirements =
                    item
                        .personnelTrainingRequirements ||
                    [];

                const requirementText =
                    formatTrainedPersonnelRequirements(
                        requirements
                    );

                const trainedVehicleTarget =
                    getTrainedPersonnelVehicleTarget(
                        requirements
                    );

                addOrUpdateVehicleRow(
                    item.unitName,
                    'Assigned trained vehicles',
                    trainedVehicleTarget,
                    'pending',
                    0
                );

                renderVehicleLoadList();

                const result =
                    selectVehiclesForTrainedPersonnelRequirements(
                        requirements,
                        'UPDATE'
                    );

                addOrUpdateVehicleRow(
                    item.unitName,
                    'Assigned trained vehicles',
                    trainedVehicleTarget,
                    result.satisfied
                        ? 'assigned'
                        : (
                            result.selectedVehicles >
                            0
                                ? 'retrying'
                                : 'missing'
                        ),
                    result.selectedVehicles
                );

                renderVehicleLoadList();

                if (
                    !result.satisfied
                ) {
                    const remainingText =
                        result.remaining
                            .filter(
                                requirement =>
                                    requirement.remaining >
                                    0
                            )
                            .map(
                                requirement => {
                                    if (
                                        requirement.requirementType ===
                                        'armed_response_atc_vehicle'
                                    ) {
                                        return (
                                            `${requirement.label}: ${requirement.remaining} ` +
                                            `dual-trained personnel still needed (2 per ATC preferred; 1 allowed as fallback)`
                                        );
                                    }

                                    if (
                                        requirement.requirementType ===
                                        'police_inspector_vehicle'
                                    ) {
                                        return (
                                            `${requirement.label}: ${requirement.remaining} ` +
                                            `Inspector-trained personnel still needed (2 per IRV preferred; 1 allowed as fallback)`
                                        );
                                    }

                                    if (
                                        requirement.requirementType ===
                                        'police_trained_irv_vehicle'
                                    ) {
                                        return (
                                            `${requirement.label}: ${requirement.remaining} ` +
                                            `trained personnel still needed (2 per IRV preferred; 1 allowed as fallback)`
                                        );
                                    }

                                    return `${requirement.label} x${requirement.remaining}`;
                                }
                            )
                            .join(', ');

                    missingAfterAttempt.push(
                        result.registryVehicleCount >
                        0
                            ? `Trained vehicles still needed: ${remainingText}`
                            : 'No trained-vehicle register was found. Run Personnel Assignment in Preview or Assign mode to build it.'
                    );
                }

                return;
            }

            const mappedName = resolveUnitName(item.unitName);
            const needed = parseInt(item.stillNeeded, 10);
            const targetMode = getOperationalRequirementTargetMode(item);

            if (!Number.isFinite(needed) || needed <= 0) return;

            const patientRule =
                getMissionUpdatePatientRequirementRule(
                    item.unitName
                );

            const patientRequirementType =
                item.patientRequirementType ||
                patientRule?.type ||
                '';

            const isTotalPatientFallback =
                !!(
                    item.isPatientAlertFallback &&
                    item.isTotalPatientRequirement &&
                    patientRequirementType
                );

            const matchingSelectedFromDom =
                countSelectedMatchingVehicles(
                    item.unitName,
                    mappedName
                );

            const trackedPatientSelected =
                isTotalPatientFallback
                    ? getTrackedPatientUnitSelections(
                        patientRequirementType
                    )
                    : 0;

            const matchingSelectedTotal =
                Math.max(
                    matchingSelectedFromDom,
                    trackedPatientSelected
                );

            const effectiveRequired =
                targetMode === 'shortage'
                    ? matchingSelectedTotal + needed
                    : needed;

            const selectedBefore =
                Math.min(
                    matchingSelectedTotal,
                    effectiveRequired
                );

            const remainingToSelect =
                Math.max(
                    0,
                    effectiveRequired -
                    selectedBefore
                );

            addOrUpdateVehicleRow(
                item.unitName,
                mappedName,
                effectiveRequired,
                remainingToSelect > 0
                    ? 'pending'
                    : 'assigned',
                selectedBefore
            );

            renderVehicleLoadList();

            if (mfDebugEnabled) {
                debugLog(
                    'UPDATE CAP',
                    `${item.unitName} -> ${mappedName} | mode=${targetMode} | panel target=${needed} | effective total=${effectiveRequired} | DOM selected=${matchingSelectedFromDom} | tracked patient selected=${trackedPatientSelected} | matching selected total=${matchingSelectedTotal} | counted toward requirement=${selectedBefore} | selecting at most=${remainingToSelect}`
                );
            }

            let updateSelectionResult = null;

            if (remainingToSelect > 0) {
                updateSelectionResult =
                    selectVehicleUnits(
                        item.unitName,
                        mappedName,
                        remainingToSelect,
                        'UPDATE'
                    );
            }

            const selectedFromCurrentDom =
                Math.min(
                    countSelectedMatchingVehicles(
                        item.unitName,
                        mappedName
                    ),
                    effectiveRequired
                );

            // MissionChief can disable or replace a vehicle row immediately
            // after it is selected. The click has succeeded, but a fresh DOM
            // count can briefly report zero and trigger a false "still
            // missing" popup. Confirm this pass using both the live DOM count
            // and the bounded number of successful clicks made by this exact
            // Mission Update attempt.
            const selectedFromThisAttempt =
                Math.min(
                    effectiveRequired,
                    selectedBefore +
                    Math.max(
                        0,
                        parseInt(
                            updateSelectionResult?.assigned,
                            10
                        ) || 0
                    )
                );

            const visualSelected =
                Math.max(
                    selectedFromCurrentDom,
                    selectedFromThisAttempt
                );

            if (patientRequirementType) {
                if (isTotalPatientFallback) {
                    setTrackedPatientUnitSelections(
                        patientRequirementType,
                        visualSelected
                    );
                } else {
                    incrementTrackedPatientUnitSelections(
                        patientRequirementType,
                        Math.max(
                            0,
                            parseInt(
                                updateSelectionResult?.assigned,
                                10
                            ) || 0
                        )
                    );
                }

                if (
                    patientRequirementType ===
                    'ambulance'
                ) {
                    vehicleLoadState.ambulances =
                        Math.max(
                            vehicleLoadState.ambulances || 0,
                            getTrackedPatientUnitSelections(
                                'ambulance'
                            )
                        );
                }
            }

            if (
                mfDebugEnabled &&
                selectedFromThisAttempt >
                    selectedFromCurrentDom
            ) {
                debugLog(
                    'UPDATE CONFIRMATION',
                    `${item.unitName} -> ${mappedName} | DOM=${selectedFromCurrentDom}/${needed} | successful clicks=${selectedFromThisAttempt}/${needed} | using successful-click confirmation`
                );
            }

            const status =
                visualSelected >= effectiveRequired
                    ? 'assigned'
                    : visualSelected > 0
                        ? 'retrying'
                        : 'missing';

            addOrUpdateVehicleRow(
                item.unitName,
                mappedName,
                effectiveRequired,
                status,
                visualSelected
            );

            renderVehicleLoadList();

            if (
                visualSelected <
                effectiveRequired
            ) {
                const remaining =
                    effectiveRequired -
                    visualSelected;

                missingAfterAttempt.push(
                    normaliseVehicleText(
                        item.unitName
                    ) === normaliseVehicleText(
                        mappedName
                    )
                        ? `${item.unitName} x${remaining}`
                        : `${item.unitName} → ${mappedName} x${remaining}`
                );
            }
        });

        if (missingAfterAttempt.length > 0) {
            if (showAlerts && !autoModeRunning) {
                alert(`Mission update units still missing:\n\n${missingAfterAttempt.join('\n')}`);
            }

            updateStatusBox("Some mission update units are missing.");
            changeDispatchBoxColor(false);

            if (autoModeRunning) {
                updateStatusBox(`Auto Mode: missing update units. Will dispatch to skip.`);
            }

            return false;
        }

        updateStatusBox(
            "Mission update vehicles and supported personnel units assigned."
        );
        changeDispatchBoxColor(true);

        if (
            missingRows.length > 0 &&
            !options.suppressUpdateLog
        ) {
            addMissionLogEntry('update', getCurrentMissionName(), `Mission update handled x${missingRows.length}`, null);
        }

        return true;
    }

    async function autoHandleMissionUpdateAfterDispatch() {
        const rows = readMissionUpdateRows();

        if (rows.length === 0) {
            updateStatusBox("No mission update found after dispatch.");
            return;
        }

        updateStatusBox("Mission update found. Assigning new units...");

        await preparePoliceVehicleSafetyForRows(
            rows,
            'AUTO POST-DISPATCH UPDATE'
        );

        const assigned = handleMissionUpdateUnits(false, rows);

        if (assigned) {
            setTimeout(() => {
                updateStatusBox("Mission update assigned. Ready to dispatch again.");
                changeDispatchBoxColor(true);
            }, 1000);
        }
    }



    function parseMissionIdFromHrefForQueueRestart(href) {
        const value = String(href || '');

        const directMatch = value.match(/\/missions\/(\d+)/i);
        if (directMatch) return directMatch[1];

        try {
            const url = new URL(value, window.location.origin);
            const missionId = url.searchParams.get('mission_id');
            if (missionId) return missionId;
        } catch (error) {}

        const anyMatch = value.match(/mission_id=(\d+)/i);
        return anyMatch ? anyMatch[1] : '';
    }

    function getCurrentMissionIdForQueueRestart() {
        const helpLink =
            getActiveMissionHelpLink();

        const helpId =
            parseMissionIdFromHrefForQueueRestart(
                helpLink
                    ? (
                        helpLink.href ||
                        helpLink.getAttribute(
                            'href'
                        )
                    )
                    : ''
            );

        if (helpId) return helpId;

        const missionInfo =
            getActiveVisibleMissionInfo();

        if (missionInfo) {
            const attrs = ['data-mission-id', 'data-id', 'mission_id', 'data-mission'];

            for (const attr of attrs) {
                const value = missionInfo.getAttribute(attr);
                if (value && /^\d+$/.test(String(value))) return String(value);
            }

            const missionLink = missionInfo.querySelector && missionInfo.querySelector('a[href*="/missions/"], a[href*="mission_id="]');
            const linkId = parseMissionIdFromHrefForQueueRestart(missionLink ? (missionLink.href || missionLink.getAttribute('href')) : '');
            if (linkId) return linkId;
        }

        return parseMissionIdFromHrefForQueueRestart(window.location.href);
    }

    function isSilentQueueWatchActive() {
        if (!MF_IS_TOP_WINDOW) return false;
        if (isManualAutoStopActive()) return false;
        if (!mfQueueRestartEnabled) return false;

        const autoActive =
            autoModeRunning === true ||
            sessionStorage.getItem('mf_auto_mode_running') === 'true' ||
            localStorage.getItem('mf_auto_mode_running') === 'true';

        if (!autoActive) return false;

        if (
            isPostTransportRehookPending() ||
            wasTransportSequenceActive() ||
            getTransportRehookLockRemaining() > 0
        ) {
            return false;
        }

        const normalQueueWait =
            sessionStorage.getItem(MF_QUEUE_WAIT_ACTIVE_FLAG) === 'true';

        const mainScreenFallback =
            !isMissionPage() &&
            !isMissionScreenVisibleForQueueRestart();

        return normalQueueWait || mainScreenFallback;
    }


    function safeQueueStatus(message) {
        try {
            updateStatusBox(message);
        } catch (error) {}
    }

    async function waitForSpecificQueueMissionToOpen(
        targetMissionId,
        previousMissionId,
        modalCountBeforeClick
    ) {
        const started = Date.now();
        const beforeCount = Number.isFinite(modalCountBeforeClick)
            ? modalCountBeforeClick
            : 0;

        while (Date.now() - started < 30000) {
            const currentMissionId = getCurrentMissionIdForQueueRestart();
            const missionScreenVisible = isMissionScreenVisibleForQueueRestart();
            const missionPage = isMissionPage();
            const modalCount = getVisibleQueueOpenModals().length;
            const urlMissionId = parseMissionIdFromHrefForQueueRestart(
                window.location.href
            );

            if (mfDebugEnabled) {
                debugLog(
                    'NEXT QUEUE OPEN',
                    `target=${targetMissionId || 'unknown'} | previous=${previousMissionId || 'unknown'} | current=${currentMissionId || 'unknown'} | url=${urlMissionId || 'unknown'} | missionPage=${missionPage ? 'yes' : 'no'} | missionVisible=${missionScreenVisible ? 'yes' : 'no'} | modals=${modalCount}`
                );
            }

            if (
                targetMissionId &&
                (
                    currentMissionId === targetMissionId ||
                    urlMissionId === targetMissionId
                ) &&
                (
                    missionPage ||
                    missionScreenVisible ||
                    modalCount > beforeCount
                )
            ) {
                return true;
            }

            if (
                currentMissionId &&
                currentMissionId !== previousMissionId &&
                (missionPage || missionScreenVisible)
            ) {
                return true;
            }

            // MissionChief creates an empty .vm--modal before inserting mission
            // content. That is already a successful single open request.
            if (modalCount > beforeCount) {
                if (mfDebugEnabled) {
                    debugLog(
                        'NEXT QUEUE OPEN',
                        `Loading modal appeared (${beforeCount} -> ${modalCount}). Treating mission as opened and blocking further Dispatch clicks.`
                    );
                }

                return true;
            }

            await wait(400);
        }

        return false;
    }


    function startSilentQueueWatcher() {
        if (!MF_IS_TOP_WINDOW) return;
        if (mfSilentQueueWatcherTimer) return;

        mfSilentQueueWatcherTimer = setInterval(async () => {
            if (isManualAutoStopActive()) return;
            if (!isSilentQueueWatchActive()) return;
            if (mfSilentQueueOpening) return;
            if (isMainMissionOpeningPending('silent-queue-watch')) return;
            if (sessionStorage.getItem(MF_QUEUE_OPENING_MISSION_FLAG) === 'true') return;

            // This catches empty/loading Vue modals as well as completed mission screens.
            if (hasVisibleQueueOpenModal('silent-queue-watch')) return;
            if (!canOpenMainMissionFromMainList('silent-queue-watch')) return;
            if (isMissionScreenVisibleForQueueRestart()) return;

            const queueCountState =
                getQueueRestartCountState();

            if (mfDebugEnabled) {
                debugLog(
                    'SILENT QUEUE',
                    `active=yes | unattendedFound=${queueCountState.found ? 'yes' : 'no'} | count=${queueCountState.found ? queueCountState.count : 'n/a'} | threshold=${queueCountState.threshold} | reached=${queueCountState.reached ? 'yes' : 'no'} | queueWait=${sessionStorage.getItem(MF_QUEUE_WAIT_ACTIVE_FLAG) || 'false'} | transportPending=${isPostTransportRehookPending() ? 'yes' : 'no'} | mainFallback=${(!isMissionPage() && !isMissionScreenVisibleForQueueRestart()) ? 'yes' : 'no'}`
                );
            }

            if (!queueCountState.reached) {
                reportQueueRestartCountWait(
                    queueCountState,
                    'silent-queue-watch'
                );
                return;
            }

            await openFirstMissionFromSilentQueueWatcher(
                'silent-threshold'
            );
        }, 2000);
    }


    async function openFirstMissionFromSilentQueueWatcher(reason) {
        if (!MF_IS_TOP_WINDOW) return;
        if (mfSilentQueueOpening) return false;
        if (!isSilentQueueWatchActive()) return false;
        if (isMainMissionOpeningPending(`silent-open-${reason}`)) return false;
        if (sessionStorage.getItem(MF_QUEUE_OPENING_MISSION_FLAG) === 'true') return false;
        if (hasVisibleQueueOpenModal(`silent-open-${reason}`)) return false;
        if (!canOpenMainMissionFromMainList(`silent-open-${reason}`)) return false;

        if (isMissionScreenVisibleForQueueRestart()) return false;

        const queueCountState =
            getQueueRestartCountState();

        if (!queueCountState.reached) {
            reportQueueRestartCountWait(
                queueCountState,
                `silent-open-${reason}`
            );
            return false;
        }

        const filterClicked =
            clickUnattendedMissionFilterForQueueRestart();

        if (mfDebugEnabled) {
            debugLog(
                'SILENT QUEUE',
                `${reason}: unattended filter ready=${filterClicked ? 'yes' : 'no'}`
            );
        }

        const searchStarted = Date.now();
        let firstMissionButton = null;

        while (Date.now() - searchStarted < 8000) {
            if (isManualAutoStopActive()) return false;
            if (hasVisibleQueueOpenModal(`silent-search-${reason}`)) return false;
            if (isMissionScreenVisibleForQueueRestart()) return false;

            firstMissionButton = findFirstMissionButtonForQueueRestart();

            if (firstMissionButton) break;

            await wait(400);
        }

        if (!firstMissionButton) {
            if (mfDebugEnabled) {
                debugLog(
                    'SILENT QUEUE',
                    `${reason}: exact first Dispatch button not found after filter refresh.`
                );
            }

            return false;
        }

        const firstMissionHref =
            firstMissionButton.getAttribute('href') ||
            firstMissionButton.href ||
            '';

        const targetMissionId =
            parseMissionIdFromHrefForQueueRestart(firstMissionHref);

        const previousMissionId = getCurrentMissionIdForQueueRestart();
        const modalCountBeforeClick = getVisibleQueueOpenModals().length;

        if (modalCountBeforeClick > 0) return false;

        if (!acquireMainMissionOpenLock(`silent-open-${reason}`, 45000)) {
            return false;
        }

        markMainMissionOpeningPending(
            targetMissionId,
            `silent-open-${reason}`,
            45000
        );

        if (mfDebugEnabled) {
            debugLog(
                'SILENT QUEUE',
                `${reason}: opening ONE exact Dispatch ${firstMissionHref || 'unknown href'} | target=${targetMissionId || 'unknown'} | previous=${previousMissionId || 'unknown'}`
            );
        }

        autoModeRunning = true;
        sessionStorage.setItem('mf_auto_mode_running', 'true');
        localStorage.setItem('mf_auto_mode_running', 'true');

        sessionStorage.removeItem(MF_QUEUE_WAIT_ACTIVE_FLAG);
        sessionStorage.removeItem(MF_FINAL_QUEUE_DISPATCH_FLAG);
        mfQueueRestartWaiting = false;

        const clicked = realClickForQueueRestart(firstMissionButton);

        if (!clicked) {
            clearMainMissionOpeningPending(
                `silent-open-${reason}-click-failed`
            );
            return false;
        }

        const opened = await waitForSpecificQueueMissionToOpen(
            targetMissionId,
            previousMissionId,
            modalCountBeforeClick
        );

        if (!opened) {
            // Do not release and retry over an existing loading modal.
            if (hasVisibleQueueOpenModal(`silent-timeout-${reason}`)) {
                clearMainMissionOpeningPending(
                    `silent-open-${reason}-loading-modal`
                );
                await resumeAutoAfterMainMissionOpen(
                    `silent-open-${reason}-loading-modal`
                );
                return true;
            }

            clearMainMissionOpeningPending(
                `silent-open-${reason}-not-confirmed`
            );

            safeQueueStatus(
                'Mission open was not confirmed. No second mission was opened.'
            );

            return false;
        }

        clearMainMissionOpeningPending(
            `silent-open-${reason}-opened`
        );

        await resumeAutoAfterMainMissionOpen(
            `silent-open-${reason}`
        );

        return true;
    }


    function clearQueueWaitFlags(reason) {
        const hadQueueWait = sessionStorage.getItem(MF_QUEUE_WAIT_ACTIVE_FLAG) === 'true';
        const hadFinalDispatch = sessionStorage.getItem(MF_FINAL_QUEUE_DISPATCH_FLAG) === 'true';
        const hadOpening = sessionStorage.getItem(MF_QUEUE_OPENING_MISSION_FLAG) === 'true';

        sessionStorage.removeItem(MF_QUEUE_WAIT_ACTIVE_FLAG);
        sessionStorage.removeItem(MF_FINAL_QUEUE_DISPATCH_FLAG);
        sessionStorage.removeItem(MF_QUEUE_OPENING_MISSION_FLAG);
        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_UNTIL_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_TARGET_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_REASON_KEY);
        mfQueueRestartWaiting = false;
        mfSilentQueueOpening = false;
        releaseMainMissionOpenLock(reason || 'clearQueueWaitFlags');

        if (reason && String(reason).toLowerCase().includes('stopped')) {
            releaseTransportRehookLock(reason || 'clearQueueWaitFlags');
        }

        if (mfDebugEnabled && (hadQueueWait || hadFinalDispatch || hadOpening)) {
            debugLog('NEXT QUEUE', `Cleared queue flags. reason=${reason || 'unknown'} | queueWait=${hadQueueWait ? 'yes' : 'no'} | finalDispatch=${hadFinalDispatch ? 'yes' : 'no'} | opening=${hadOpening ? 'yes' : 'no'}`);
        }
    }


    function installManualMissionClickFlagClearer() {
        if (window.mfManualMissionClickFlagClearerInstalled) return;
        window.mfManualMissionClickFlagClearerInstalled = true;

        document.addEventListener('click', function(event) {
            if (!event.isTrusted) return;

            const target = event.target && event.target.closest
                ? event.target.closest(
                    'a.mission-alarm-button[id^="alarm_button_"][href*="/missions/"]'
                )
                : null;

            if (!target) return;

            const href = target.getAttribute('href') || target.href || '';
            const targetMissionId =
                parseMissionIdFromHrefForQueueRestart(href);

            // A manual Dispatch click must block the automatic watcher.
            // The old code cleared the lock here, which caused a second automatic click.
            releaseMainMissionOpenLock('manual dispatch replacing old lock');

            markMainMissionOpeningPending(
                targetMissionId,
                'trusted manual Dispatch click',
                45000
            );

            if (mfDebugEnabled) {
                debugLog(
                    'MISSION OPEN OWNER',
                    `Trusted manual Dispatch click owns the open | target=${targetMissionId || 'unknown'}`
                );
            }

            setTimeout(async () => {
                const opened = await waitForSpecificQueueMissionToOpen(
                    targetMissionId,
                    '',
                    0
                );

                clearMainMissionOpeningPending(
                    opened
                        ? 'trusted manual Dispatch opened'
                        : 'trusted manual Dispatch timeout'
                );

                if (opened && autoModeRunning && !isManualAutoStopActive()) {
                    await resumeAutoAfterMainMissionOpen(
                        'trusted-manual-dispatch'
                    );
                }
            }, 100);
        }, true);
    }


    function toggleAutoMode() {
        if (autoModeRunning) {
            stopAutoMode('Auto Mode stopped.');
            return;
        }

        startAutoMode();
    }

    function startAutoMode() {
        clearManualAutoStop('auto mode manually started');

        if (!isMissionPage()) {
            updateStatusBox('Open a mission first, then start Auto Mode.');
            return;
        }

        clearQueueWaitFlags('auto mode manually started');
        clearAllTransportAutomationFlags('auto mode manually started');
        clearAutoPostDispatchUpgradeState(
            'auto mode manually started'
        );

        const existingAdvanceState =
            readAutoAdvanceAfterDispatchState();

        if (
            existingAdvanceState?.mode === 'auto'
        ) {
            clearAutoAdvanceAfterDispatchState(
                'auto mode manually started'
            );
        }

        clearAutoSelectionMissionGuard(
            'Auto Mode manually started'
        );

        resetVehicleLoadState();

        autoModeRunning = true;
        sessionStorage.setItem('mf_auto_mode_running', 'true');
        localStorage.setItem('mf_auto_mode_running', 'true');

        updateAutoModeButton();
        updateStatusBox('Auto Mode started.');
        startSilentQueueWatcher();
        startGlobalTransportApproachWatcher();
        startBruteApproachTransportWatcher();
        startPostTransportRehookWatcher();
        runAutoModeLoop();
    }

    function stopAutoMode(message) {
        clearAutoPostDispatchUpgradeState(
            message || 'auto mode stopped'
        );

        clearAutoAdvanceAfterDispatchState(
            message || 'auto mode stopped'
        );

        clearAutoSelectionMissionGuard(
            message ||
            'Auto Mode stopped'
        );

        resetVehicleLoadState();

        setManualAutoStop(
            message ||
            'auto mode stopped'
        );

        updateAutoModeButton();

        if (message) {
            updateStatusBox(message);
        } else {
            updateStatusBox('Auto Mode stopped.');
        }
    }


    function getNextMissionQueueState() {
        const button = document.querySelector('#mission_next_mission_btn');

        if (!button) {
            return {
                exists: false,
                count: null,
                title: '',
                text: '',
                href: '',
                className: ''
            };
        }

        const title = button.getAttribute('title') || '';
        const text = (button.textContent || '').replace(/\s+/g, ' ').trim();
        const href = button.getAttribute('href') || '';
        const className = button.className || '';

        const titleMatch = title.match(/Next Mission\s*\((\d+)\)/i);
        const textMatches = text.match(/\d+/g);

        const titleCount = titleMatch ? parseInt(titleMatch[1], 10) : null;
        const textCount = textMatches && textMatches.length ? parseInt(textMatches[textMatches.length - 1], 10) : null;

        const count = Number.isFinite(titleCount)
            ? titleCount
            : Number.isFinite(textCount)
                ? textCount
                : null;

        return {
            exists: true,
            count,
            title,
            text,
            href,
            className
        };
    }

    function isFinalQueueSignal(queueState) {
        // Only 0 is the end. 1 still means there is one next mission after the current one.
        return !!mfQueueRestartEnabled
            && !!queueState
            && queueState.exists
            && queueState.count === 0;
    }

    function logQueueState(label, queueState, finalSignal) {
        if (!mfDebugEnabled) return;

        const count = queueState && queueState.count !== null ? queueState.count : 'unknown';
        const exists = queueState && queueState.exists ? 'yes' : 'no';

        debugLog(
            'NEXT QUEUE',
            `${label} | exists=${exists} | count=${count} | title="${queueState ? queueState.title : ''}" | text="${queueState ? queueState.text : ''}" | href="${queueState ? queueState.href : ''}" | final=${finalSignal ? 'yes' : 'no'} | flag=${sessionStorage.getItem(MF_FINAL_QUEUE_DISPATCH_FLAG) === 'true' ? 'yes' : 'no'}`
        );
    }

    function isVisibleForQueueRestart(element) {
        if (!element) return false;

        const rect = element.getBoundingClientRect();
        const style = window.getComputedStyle(element);

        return rect.width > 0
            && rect.height > 0
            && style.display !== 'none'
            && style.visibility !== 'hidden'
            && style.opacity !== '0';
    }

    function isElementVisible(element) {
        if (!element) return false;

        try {
            if (typeof mfIsVisibleInOwnDocument === 'function') {
                return mfIsVisibleInOwnDocument(element);
            }
        } catch (error) {}

        try {
            return isVisibleForQueueRestart(element);
        } catch (error) {
            try {
                return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
            } catch (innerError) {
                return false;
            }
        }
    }

    function isManualAutoStopActive() {
        return sessionStorage.getItem(MF_MANUAL_AUTO_STOP_FLAG) === 'true' ||
            localStorage.getItem(MF_MANUAL_AUTO_STOP_FLAG) === 'true';
    }

    function clearManualAutoStop(reason) {
        const hadStop = isManualAutoStopActive();

        sessionStorage.removeItem(MF_MANUAL_AUTO_STOP_FLAG);
        localStorage.removeItem(MF_MANUAL_AUTO_STOP_FLAG);

        if (hadStop && mfDebugEnabled) {
            debugLog('AUTO STOP GUARD', `Manual stop cleared. reason=${reason || 'unknown'}`);
        }
    }

    function stopAllBackgroundAutomationTimers(reason) {
        const timers = [
            ['silentQueue', 'mfSilentQueueWatcherTimer'],
            ['globalTransport', 'mfGlobalTransportWatcherTimer'],
            ['bruteTransport', 'mfBruteApproachWatcherTimer'],
            ['postTransport', 'mfPostTransportRehookTimer']
        ];

        if (mfSilentQueueWatcherTimer) {
            clearInterval(mfSilentQueueWatcherTimer);
            mfSilentQueueWatcherTimer = null;
        }

        if (mfGlobalTransportWatcherTimer) {
            clearInterval(mfGlobalTransportWatcherTimer);
            mfGlobalTransportWatcherTimer = null;
        }

        if (mfBruteApproachWatcherTimer) {
            clearInterval(mfBruteApproachWatcherTimer);
            mfBruteApproachWatcherTimer = null;
        }

        if (mfPostTransportRehookTimer) {
            clearInterval(mfPostTransportRehookTimer);
            mfPostTransportRehookTimer = null;
        }

        mfTransportSequenceActive = false;
        mfTransportContinuationRunning = false;
        mfPostTransportOpening = false;
        mfGlobalTransportClicking = false;
        mfBruteApproachClicking = false;
        mfTransportApproachClicking = false;
        mfSilentQueueOpening = false;
        releaseMainMissionOpenLock(reason || 'stop timers');
        releaseTransportRehookLock(reason || 'stop timers');

        if (mfDebugEnabled) {
            debugLog('AUTO STOP GUARD', `Stopped background timers. reason=${reason || 'unknown'}`);
        }
    }

    function setManualAutoStop(reason) {
        sessionStorage.setItem(MF_MANUAL_AUTO_STOP_FLAG, 'true');
        localStorage.setItem(MF_MANUAL_AUTO_STOP_FLAG, 'true');

        autoModeRunning = false;
        autoModeLoopActive = false;

        sessionStorage.setItem('mf_auto_mode_running', 'false');
        localStorage.setItem('mf_auto_mode_running', 'false');

        clearQueueWaitFlags(reason || 'manual stop');
        clearAllTransportAutomationFlags(reason || 'manual stop');
        stopAllBackgroundAutomationTimers(reason || 'manual stop');

        if (mfDebugEnabled) {
            debugLog('AUTO STOP GUARD', `Manual stop set. reason=${reason || 'unknown'}`);
        }
    }


    function getCurrentMissionAlertScopes() {
        return Array.from(
            new Set(
                getActiveMissionRequirementContexts()
                    .map(
                        context =>
                            context.root
                    )
            )
        );
    }

    function areCurrentMissionUpdateRowsFullySelected() {
        const rows =
            readMissionUpdateRows({
                silent: true
            });

        if (
            !Array.isArray(rows) ||
            rows.length === 0
        ) {
            return false;
        }

        return rows.every(row => {
            if (
                row
                    .isTrainedPersonnelRequirement
            ) {
                return areTrainedPersonnelRequirementsSatisfied(
                    row.personnelTrainingRequirements
                );
            }

            const needed =
                Math.max(
                    0,
                    parseInt(
                        row.stillNeeded,
                        10
                    ) || 0
                );

            if (needed <= 0) {
                return true;
            }

            const mappedName =
                resolveUnitName(
                    row.unitName
                );

            return (
                countSelectedMatchingVehicles(
                    row.unitName,
                    mappedName
                ) >= needed
            );
        });
    }

    function getVisibleInlineProblemAlertText() {
        // Important:
        // This must only read alerts from the ACTIVE mission window.
        // The main mission list also contains many red alerts and those must not
        // stop Auto Mode or block the post-transport rehook.
        const scopes = getCurrentMissionAlertScopes();

        if (!scopes.length) return '';

        const alerts = [];

        scopes.forEach(scope => {
            scope.querySelectorAll(
                '#missing_text.alert-danger, .alert-missing-vehicles, .alert-danger[id^="missing_"], .alert-danger'
            ).forEach(alert => {
                if (!alerts.includes(alert)) alerts.push(alert);
            });
        });

        for (const alert of alerts) {
            try {
                if (!isElementVisible(alert)) continue;
            } catch (error) {}

            const text = (alert.innerText || alert.textContent || '').replace(/\s+/g, ' ').trim();
            if (!text) continue;

            const lower = text.toLowerCase();

            if (
                lower.includes('missing personnel:') &&
                hasSupportedMissingPersonnelUpdate(text) &&
                !lower.includes('missing vehicles:')
            ) {
                continue;
            }

            const isActionableMissionUpdateAlert =
                lower.includes(
                    'missing vehicles:'
                ) ||
                lower.includes(
                    'missing vehicle:'
                ) ||
                lower.includes(
                    'we need:'
                ) ||
                (
                    lower.includes(
                        'missing personnel:'
                    ) &&
                    hasSupportedMissingPersonnelUpdate(
                        text
                    )
                );

            if (
                isActionableMissionUpdateAlert &&
                areCurrentMissionUpdateRowsFullySelected()
            ) {
                // MissionChief keeps the red update text visible until
                // Dispatch. Do not turn the panel back to not-ready when
                // every parsed update requirement is already selected.
                continue;
            }

            if (
                lower.includes('missing vehicles:') ||
                lower.includes('missing vehicle:') ||
                (
                    lower.includes('missing personnel:') &&
                    !hasSupportedMissingPersonnelUpdate(text)
                ) ||
                lower.includes('we need:') ||
                lower.includes('something went wrong') ||
                lower.includes('has not enough personal') ||
                lower.includes('has not enough personnel') ||
                lower.includes('right qualification')
            ) {
                return text;
            }
        }

        return '';
    }

    function normaliseVisibleRequirementName(rawName) {
        return String(rawName || '')
            .replace(/\(.*?\)/g, ' ')
            .replace(/\bmin\.\s*\d+\b/gi, ' ')
            .replace(/\bx\s*\d+\b/gi, ' ')
            .replace(/[:;,.]/g, ' ')
            .replace(/\s+/g, ' ')
            .trim();
    }

    function parseVisibleMissionRequirementRows() {
        if (!isCurrentMissionExecutionOwner('visible fallback requirement read')) {
            return [];
        }

        synchroniseMissionInstanceState('visible fallback read');

        const activeRoots =
            getActiveMissionRequirementContexts()
                .map(
                    context =>
                        context.root
                );

        const candidates =
            activeRoots.flatMap(root => {
                const values = [];

                if (
                    root.nodeType !== 9 &&
                    root.matches &&
                    root.matches(
                        '#mission_help, #mission_general_info, ' +
                        '#mission_content, #iframe-inside-container, ' +
                        '.mission_help, .mission_content'
                    )
                ) {
                    values.push(
                        root
                    );
                }

                try {
                    values.push(
                        ...root.querySelectorAll(
                            '#mission_help, #mission_general_info, ' +
                            '#mission_content, #iframe-inside-container, ' +
                            '.mission_help, .mission_content'
                        )
                    );
                } catch (_error) {}

                return values;
            });

        const scopes =
            Array.from(
                new Set(
                    candidates
                )
            ).filter(
                scope =>
                    isMissionElementVisible(
                        scope
                    )
            );

        const rows = [];
        const seen = new Set();

        function addRow(name, amount, source) {
            let cleanName = normaliseVisibleRequirementName(name);
            let required = Math.max(1, parseInt(amount || '1', 10) || 1);

            if (!cleanName) return;
            if (cleanName.length > 90) return;
            if (shouldIgnoreRequiredMinimumRequirement(cleanName)) return;

            const sarPersonnelConversion =
                getSarPersonnelVehicleRequirement(
                    cleanName,
                    required
                );

            if (sarPersonnelConversion) {
                cleanName =
                    sarPersonnelConversion.unitName;

                required =
                    sarPersonnelConversion.stillNeeded;

                if (mfDebugEnabled) {
                    debugLog(
                        'VISIBLE SAR PERSONNEL',
                        `${sarPersonnelConversion.personnelRequirement} -> ${sarPersonnelConversion.unitName} x${sarPersonnelConversion.stillNeeded} (${sarPersonnelConversion.personnelPerVehicle} personnel per vehicle)`
                    );
                }
            }

            const lower = cleanName.toLowerCase();

            // Avoid scraping general text/buttons as fake requirements.
            if (
                lower.includes('patient badge') ||
                lower.includes('credits') ||
                lower.includes('reward') ||
                lower.includes('mission') ||
                lower.includes('alliance') ||
                lower.includes('dispatch') ||
                lower.includes('transport requested') ||
                lower.includes('next mission') ||
                lower.includes('start') ||
                lower.includes('status')
            ) {
                return;
            }

            const mappedName =
                crossReference[cleanName] ||
                crossReference[cleanName.replace(/s$/i, '')] ||
                resolveUnitName(cleanName) ||
                cleanName;

            const key = `${cleanName.toLowerCase()}|${mappedName}|${required}`;

            if (seen.has(key)) return;
            seen.add(key);

            rows.push({
                unitName: cleanName,
                originalName: cleanName,
                mappedName,
                stillNeeded: required,
                required,
                selected: 0,
                status: 'pending',
                source: source || 'visible fallback'
            });
        }

        for (const scope of scopes) {
            const text = (scope.innerText || scope.textContent || '').replace(/\s+/g, ' ').trim();

            if (!text) continue;

            // Visible fallback is deliberately strict. Only exact
            // MissionChief "We need ..." statements are accepted.
            // A unit name merely appearing elsewhere on the page must never
            // create a requirement.
            const needRegex =
                /\bWe\s+need\s*:?\s+([A-Za-z0-9/&()'’\- ]{3,80}?)(?:\s+x\s*(\d+)|\s*\((?:min\.\s*)?(\d+)\)|(?=\s+We\s+need\b|$))/gi;

            let match;

            while (
                (
                    match =
                        needRegex.exec(
                            text
                        )
                )
            ) {
                addRow(
                    match[1],
                    match[2] ||
                    match[3] ||
                    '1',
                    'visible-explicit-we-need'
                );
            }
        }

        if (mfDebugEnabled) {
            if (rows.length) {
                debugLog('VISIBLE FALLBACK', `Found ${rows.length} visible fallback row(s): ${rows.map(row => `${row.originalName} x${row.required} -> ${row.mappedName}`).join(' | ')}`);
            } else {
                debugLog('VISIBLE FALLBACK', 'No visible fallback rows found.');
            }
        }

        return rows;
    }

    function isCurrentMissionWindowOpenStrict(reason) {
        const selectors = [
            '#lightbox_close_inside',
            '#mission_general_info',
            '#mission_content',
            '#iframe-inside-container',
            '#mission_caption',
            '#missionH1'
        ];

        const visible = selectors.some(selector => {
            const element = document.querySelector(selector);
            if (!element) return false;

            try {
                return isElementVisible(element);
            } catch (error) {
                return true;
            }
        });

        if (visible && mfDebugEnabled) {
            debugLog('QUEUE OPEN GUARD', `${reason || 'check'} | current mission window still visible`);
        }

        return visible;
    }

    function getMainMissionOpenLockRemaining() {
        const until = parseInt(sessionStorage.getItem(MF_MAIN_MISSION_OPEN_LOCK_KEY) || '0', 10);
        return Math.max(0, until - Date.now());
    }

    function isMainMissionOpenLockActive(reason) {
        const remaining = getMainMissionOpenLockRemaining();

        if (remaining > 0) {
            if (mfDebugEnabled) {
                debugLog('QUEUE OPEN GUARD', `${reason || 'check'} | open lock active ${remaining}ms | ${sessionStorage.getItem(MF_MAIN_MISSION_OPEN_REASON_KEY) || ''}`);
            }
            return true;
        }

        sessionStorage.removeItem(MF_MAIN_MISSION_OPEN_LOCK_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_OPEN_REASON_KEY);
        return false;
    }

    function acquireMainMissionOpenLock(reason, durationMs) {
        if (isManualAutoStopActive()) return false;
        if (isMainMissionOpenLockActive(`acquire-${reason}`)) return false;

        const duration = Number.isFinite(durationMs) ? durationMs : 22000;
        sessionStorage.setItem(MF_MAIN_MISSION_OPEN_LOCK_KEY, String(Date.now() + duration));
        sessionStorage.setItem(MF_MAIN_MISSION_OPEN_REASON_KEY, reason || 'unknown');

        if (mfDebugEnabled) {
            debugLog('QUEUE OPEN GUARD', `ACQUIRED | reason=${reason || 'unknown'} | duration=${duration}`);
        }

        return true;
    }

    function releaseMainMissionOpenLock(reason) {
        const hadLock = !!sessionStorage.getItem(MF_MAIN_MISSION_OPEN_LOCK_KEY);

        sessionStorage.removeItem(MF_MAIN_MISSION_OPEN_LOCK_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_OPEN_REASON_KEY);

        if (hadLock && mfDebugEnabled) {
            debugLog('QUEUE OPEN GUARD', `RELEASED | reason=${reason || 'unknown'}`);
        }
    }

    function shouldBlockOpeningNewMissionForTransport(reason) {
        if (isManualAutoStopActive()) return true;

        let visibleApproach = false;
        let vehicleTransport = false;
        let policeTransport = false;

        try {
            visibleApproach = !!mfFindAnyVisibleApproachButtonDeep();
        } catch (error) {}

        try {
            vehicleTransport = !!(
                typeof isVehicleTransportModalVisible === 'function' &&
                isVehicleTransportModalVisible()
            );
        } catch (error) {}

        try {
            policeTransport = !!mfIsPoliceOrPrisonerTransportActive();
        } catch (error) {}

        const lastTransportClick = Math.max(
            typeof mfLastTransportClickAt !== 'undefined' ? mfLastTransportClickAt || 0 : 0,
            typeof mfTransportLastClickAt !== 'undefined' ? mfTransportLastClickAt || 0 : 0,
            typeof mfBruteLastClickAt !== 'undefined' ? mfBruteLastClickAt || 0 : 0
        );

        const lastClickAge = Date.now() - lastTransportClick;
        const refreshingAfterApproach =
            lastTransportClick > 0 &&
            lastClickAge >= 0 &&
            lastClickAge < 6500;

        const blocked =
            visibleApproach ||
            vehicleTransport ||
            policeTransport ||
            refreshingAfterApproach;

        if (blocked && mfDebugEnabled) {
            debugLog(
                'TRANSPORT REHOOK BLOCK',
                `${reason || 'check'} | approach=${visibleApproach ? 'yes' : 'no'} | vehicle=${vehicleTransport ? 'yes' : 'no'} | police=${policeTransport ? 'yes' : 'no'} | lastClickAge=${lastClickAge}`
            );
        }

        return blocked;
    }

    function getTransportRehookLockRemaining() {
        const until = parseInt(sessionStorage.getItem(MF_TRANSPORT_REHOOK_LOCK_KEY) || '0', 10);
        return Math.max(0, until - Date.now());
    }

    function isTransportRehookLockActive(reason) {
        const remaining = getTransportRehookLockRemaining();

        if (remaining > 0) {
            if (mfDebugEnabled) {
                debugLog(
                    'TRANSPORT REHOOK OWNER',
                    `${reason || 'check'} | locked ${remaining}ms | ${sessionStorage.getItem(MF_TRANSPORT_REHOOK_REASON_KEY) || ''}`
                );
            }

            return true;
        }

        sessionStorage.removeItem(MF_TRANSPORT_REHOOK_LOCK_KEY);
        sessionStorage.removeItem(MF_TRANSPORT_REHOOK_REASON_KEY);
        return false;
    }

    function acquireTransportRehookLock(reason, durationMs) {
        if (isManualAutoStopActive()) return false;
        if (isTransportRehookLockActive(`acquire-${reason}`)) return false;

        const duration = Number.isFinite(durationMs) ? durationMs : 26000;

        sessionStorage.setItem(MF_TRANSPORT_REHOOK_LOCK_KEY, String(Date.now() + duration));
        sessionStorage.setItem(MF_TRANSPORT_REHOOK_REASON_KEY, reason || 'unknown');

        if (mfDebugEnabled) {
            debugLog('TRANSPORT REHOOK OWNER', `ACQUIRED | reason=${reason || 'unknown'} | duration=${duration}`);
        }

        return true;
    }

    function releaseTransportRehookLock(reason) {
        const hadLock = !!sessionStorage.getItem(MF_TRANSPORT_REHOOK_LOCK_KEY);

        sessionStorage.removeItem(MF_TRANSPORT_REHOOK_LOCK_KEY);
        sessionStorage.removeItem(MF_TRANSPORT_REHOOK_REASON_KEY);

        if (hadLock && mfDebugEnabled) {
            debugLog('TRANSPORT REHOOK OWNER', `RELEASED | reason=${reason || 'unknown'}`);
        }
    }

    function getVisibleQueueOpenModals() {
        const candidates = Array.from(document.querySelectorAll(
            '.vm--modal, .modal, .lightbox, #lightbox_box'
        ));

        return candidates.filter(element => {
            try {
                return isVisibleForQueueRestart(element);
            } catch (error) {
                try {
                    const rect = element.getBoundingClientRect();
                    const style = window.getComputedStyle(element);

                    return rect.width > 0 &&
                        rect.height > 0 &&
                        style.display !== 'none' &&
                        style.visibility !== 'hidden';
                } catch (innerError) {
                    return false;
                }
            }
        });
    }

    function hasVisibleQueueOpenModal(reason) {
        const modals = getVisibleQueueOpenModals();
        const visible = modals.length > 0;

        if (visible && mfDebugEnabled) {
            debugLog(
                'MISSION OPEN MODAL GUARD',
                `${reason || 'check'} | visible loading/modal window(s)=${modals.length}`
            );
        }

        return visible;
    }

    function getMainMissionPendingRemaining() {
        const until = parseInt(
            sessionStorage.getItem(MF_MAIN_MISSION_PENDING_UNTIL_KEY) || '0',
            10
        );

        return Math.max(0, until - Date.now());
    }

    function isMainMissionOpeningPending(reason) {
        const remaining = getMainMissionPendingRemaining();

        if (remaining > 0) {
            if (mfDebugEnabled) {
                debugLog(
                    'MISSION OPEN OWNER',
                    `${reason || 'check'} | pending ${remaining}ms | target=${sessionStorage.getItem(MF_MAIN_MISSION_PENDING_TARGET_KEY) || 'unknown'} | owner=${sessionStorage.getItem(MF_MAIN_MISSION_PENDING_REASON_KEY) || 'unknown'}`
                );
            }

            return true;
        }

        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_UNTIL_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_TARGET_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_REASON_KEY);

        return false;
    }

    function markMainMissionOpeningPending(targetMissionId, reason, durationMs) {
        const duration = Number.isFinite(durationMs) ? durationMs : 45000;
        const until = Date.now() + duration;

        sessionStorage.setItem(MF_MAIN_MISSION_PENDING_UNTIL_KEY, String(until));
        sessionStorage.setItem(
            MF_MAIN_MISSION_PENDING_TARGET_KEY,
            String(targetMissionId || '')
        );
        sessionStorage.setItem(
            MF_MAIN_MISSION_PENDING_REASON_KEY,
            String(reason || 'unknown')
        );
        sessionStorage.setItem(MF_QUEUE_OPENING_MISSION_FLAG, 'true');

        mfSilentQueueOpening = true;

        const currentLockUntil = parseInt(
            sessionStorage.getItem(MF_MAIN_MISSION_OPEN_LOCK_KEY) || '0',
            10
        );

        if (!Number.isFinite(currentLockUntil) || currentLockUntil < until) {
            sessionStorage.setItem(MF_MAIN_MISSION_OPEN_LOCK_KEY, String(until));
            sessionStorage.setItem(
                MF_MAIN_MISSION_OPEN_REASON_KEY,
                `pending-${reason || 'unknown'}`
            );
        }

        if (mfDebugEnabled) {
            debugLog(
                'MISSION OPEN OWNER',
                `ACQUIRED | target=${targetMissionId || 'unknown'} | reason=${reason || 'unknown'} | duration=${duration}`
            );
        }
    }

    function clearMainMissionOpeningPending(reason) {
        const hadPending =
            !!sessionStorage.getItem(MF_MAIN_MISSION_PENDING_UNTIL_KEY) ||
            sessionStorage.getItem(MF_QUEUE_OPENING_MISSION_FLAG) === 'true';

        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_UNTIL_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_TARGET_KEY);
        sessionStorage.removeItem(MF_MAIN_MISSION_PENDING_REASON_KEY);
        sessionStorage.removeItem(MF_QUEUE_OPENING_MISSION_FLAG);

        mfSilentQueueOpening = false;
        releaseMainMissionOpenLock(reason || 'clear mission opening pending');

        if (hadPending && mfDebugEnabled) {
            debugLog(
                'MISSION OPEN OWNER',
                `RELEASED | reason=${reason || 'unknown'}`
            );
        }
    }

    async function resumeAutoAfterMainMissionOpen(reason) {
        const started = Date.now();

        while (Date.now() - started < 45000) {
            if (isManualAutoStopActive()) return false;

            if (isMissionPage() && isMissionScreenVisibleForQueueRestart()) {
                await waitForMissionReady();

                autoModeRunning = true;
                sessionStorage.setItem('mf_auto_mode_running', 'true');
                localStorage.setItem('mf_auto_mode_running', 'true');

                try {
                    updateStatusBox('Mission opened. Auto Mode continuing...');
                } catch (error) {}

                if (!autoModeLoopActive) {
                    setTimeout(() => {
                        if (
                            autoModeRunning &&
                            !autoModeLoopActive &&
                            !isManualAutoStopActive()
                        ) {
                            runAutoModeLoop();
                        }
                    }, 100);
                }

                return true;
            }

            // A visible empty modal means MissionChief is still loading the mission.
            // Keep waiting, but never open another mission over it.
            if (hasVisibleQueueOpenModal(`resume-${reason}`)) {
                await wait(500);
                continue;
            }

            // A direct mission URL may appear before the mission content.
            if (/\/missions\/\d+/i.test(window.location.pathname)) {
                await wait(500);
                continue;
            }

            await wait(500);
        }

        if (mfDebugEnabled) {
            debugLog(
                'MISSION OPEN OWNER',
                `${reason || 'unknown'} | mission content did not become ready within 45 seconds`
            );
        }

        return false;
    }


    function canOpenMainMissionFromMainList(reason) {
        if (isManualAutoStopActive()) return false;
        if (isMainMissionOpeningPending(reason || 'main-list-open')) return false;
        if (isMainMissionOpenLockActive(reason || 'main-list-open')) return false;
        if (shouldBlockOpeningNewMissionForTransport(reason || 'main-list-open')) return false;

        // A blank/loading MissionChief modal is still an active open request.
        // Never click another Dispatch button while one exists.
        if (hasVisibleQueueOpenModal(reason || 'main-list-open')) {
            return false;
        }

        if (isCurrentMissionWindowOpenStrict(reason || 'main-list-open')) {
            try {
                recordIssueEvent('MAIN LIST OPEN BLOCKED', {
                    reason: reason || 'unknown',
                    problemAlert: getVisibleInlineProblemAlertText(),
                    finalFlag: sessionStorage.getItem(MF_FINAL_QUEUE_DISPATCH_FLAG),
                    queueOpening: sessionStorage.getItem(MF_QUEUE_OPENING_MISSION_FLAG)
                }, true);
            } catch (error) {}

            return false;
        }

        return true;
    }


    function invalidateTransportCaches() {
        mfTransportDocumentCache = {
            expiresAt: 0,
            documents: []
        };

        mfTransportScopeCache = {
            expiresAt: 0,
            scopes: []
        };
    }

    function mfGetAccessibleDocumentsForTransport(forceRefresh = false) {
        const now = Date.now();
        const cachedDocuments = mfTransportDocumentCache.documents;

        if (
            !forceRefresh &&
            now < mfTransportDocumentCache.expiresAt &&
            cachedDocuments.every(isCachedMissionDocumentUsable)
        ) {
            return cachedDocuments;
        }

        const docs = [document];

        Array.from(document.querySelectorAll('iframe')).forEach(iframe => {
            try {
                const doc =
                    iframe.contentDocument ||
                    iframe.contentWindow?.document;

                if (doc?.body && !docs.includes(doc)) {
                    docs.push(doc);
                }
            } catch (_error) {
                // Cross-origin or blocked iframe; ignore.
            }
        });

        mfTransportDocumentCache = {
            expiresAt: now + 500,
            documents: docs
        };

        return docs;
    }

    function mfHasPotentialTransportUi() {
        for (const candidateDocument of mfGetAccessibleDocumentsForTransport()) {
            try {
                const path = candidateDocument.location?.pathname || '';

                if (path.startsWith('/vehicles/')) {
                    return true;
                }
            } catch (_error) {}

            try {
                const surface = candidateDocument.querySelector(
                    '.vehicle-window, .redesign-wrapper[type="vehicle"]'
                );

                if (surface && mfIsVisibleInOwnDocument(surface)) {
                    return true;
                }
            } catch (_error) {}

            try {
                const approachButtons = candidateDocument.querySelectorAll(
                    '.vm--modal button.btn-success, ' +
                    '.modal button.btn-success, ' +
                    '.lightbox button.btn-success'
                );

                for (const button of approachButtons) {
                    const text = mfBruteNormaliseText(
                        button.textContent || button.value || ''
                    ).toLowerCase();

                    if (
                        text === 'approach' &&
                        mfIsVisibleInOwnDocument(button)
                    ) {
                        return true;
                    }
                }
            } catch (_error) {}
        }

        return false;
    }

    function mfGetSharedTransportLastClickAt() {
        return parseInt(
            sessionStorage.getItem(MF_TRANSPORT_LAST_CLICK_AT_KEY) || '0',
            10
        ) || 0;
    }

    function mfAcquireSharedTransportClick(reason) {
        const now = Date.now();
        const lockUntil = parseInt(
            sessionStorage.getItem(MF_TRANSPORT_CLICK_LOCK_UNTIL_KEY) || '0',
            10
        ) || 0;

        if (lockUntil > now) {
            if (mfDebugEnabled) {
                debugLog(
                    'TRANSPORT CLICK OWNER',
                    `${reason || 'click'} blocked | previous=${sessionStorage.getItem(MF_TRANSPORT_LAST_CLICK_REASON_KEY) || 'unknown'}`
                );
            }
            return false;
        }

        sessionStorage.setItem(
            MF_TRANSPORT_CLICK_LOCK_UNTIL_KEY,
            String(now + 5200)
        );
        sessionStorage.setItem(
            MF_TRANSPORT_LAST_CLICK_AT_KEY,
            String(now)
        );
        sessionStorage.setItem(
            MF_TRANSPORT_LAST_CLICK_REASON_KEY,
            String(reason || 'unknown')
        );

        return true;
    }

    function mfMarkTransportOwner(button, reason) {
        const modal = button && button.closest
            ? button.closest('.vm--modal, .modal, .lightbox')
            : null;

        mfTransportOwnerModal = modal;
        mfTransportOwnerApproachGoneAt = 0;
        mfTransportOwnerCloseAttemptedAt = 0;
        mfTransportMainStableAt = 0;

        if (modal) {
            try {
                modal.setAttribute('data-mf-transport-owner', 'true');
                modal.setAttribute(
                    'data-mf-transport-owner-reason',
                    String(reason || 'unknown')
                );
            } catch (error) {}
        }

        if (mfDebugEnabled) {
            debugLog(
                'TRANSPORT MODAL OWNER',
                `Marked | reason=${reason || 'unknown'} | modal=${modal ? 'yes' : 'no'}`
            );
        }
    }

    function mfGetTransportOwnerModal() {
        if (mfTransportOwnerModal && mfTransportOwnerModal.isConnected) {
            return mfTransportOwnerModal;
        }

        for (const doc of mfGetAccessibleDocumentsForTransport()) {
            try {
                const marked = doc.querySelector(
                    '[data-mf-transport-owner="true"]'
                );

                if (marked) {
                    mfTransportOwnerModal = marked;
                    return marked;
                }
            } catch (error) {}
        }

        const lastClickAt = mfGetSharedTransportLastClickAt();

        if (
            isPostTransportRehookPending() &&
            lastClickAt > 0 &&
            Date.now() - lastClickAt < 30000
        ) {
            for (const doc of mfGetAccessibleDocumentsForTransport()) {
                try {
                    const modals = Array.from(
                        doc.querySelectorAll('.vm--modal, .modal, .lightbox')
                    ).filter(modal => {
                        if (!mfIsVisibleInOwnDocument(modal)) return false;

                        const modalText = (
                            modal.innerText ||
                            modal.textContent ||
                            ''
                        ).replace(/\s+/g, ' ').trim();

                        const hasMission = !!modal.querySelector(
                            '#mission_general_info, #mission_content, #mission_caption, #missionH1'
                        );

                        const hasApproach =
                            mfGetExactVisibleApproachButtons(modal).length > 0;

                        return !hasMission &&
                            !hasApproach &&
                            modalText.length < 160;
                    });

                    if (modals.length) {
                        const modal = modals[modals.length - 1];
                        modal.setAttribute(
                            'data-mf-transport-owner',
                            'true'
                        );
                        mfTransportOwnerModal = modal;
                        return modal;
                    }
                } catch (error) {}
            }
        }

        return null;
    }

    function mfClearTransportOwner(reason) {
        for (const doc of mfGetAccessibleDocumentsForTransport()) {
            try {
                doc.querySelectorAll(
                    '[data-mf-transport-owner="true"]'
                ).forEach(modal => {
                    modal.removeAttribute('data-mf-transport-owner');
                    modal.removeAttribute(
                        'data-mf-transport-owner-reason'
                    );
                });
            } catch (error) {}
        }

        mfTransportOwnerModal = null;
        mfTransportOwnerApproachGoneAt = 0;
        mfTransportOwnerCloseAttemptedAt = 0;
        mfTransportMainStableAt = 0;

        if (mfDebugEnabled) {
            debugLog(
                'TRANSPORT MODAL OWNER',
                `Cleared | reason=${reason || 'unknown'}`
            );
        }
    }

    function mfTransportShellReadyForRehook(reason) {
        const now = Date.now();
        const lastClickAt = Math.max(
            mfGetSharedTransportLastClickAt(),
            mfTransportLastClickAt || 0,
            mfBruteLastClickAt || 0,
            mfLastTransportClickAt || 0
        );

        const modal = mfGetTransportOwnerModal();

        if (modal) {
            let visible = false;

            try {
                visible = mfIsVisibleInOwnDocument(modal);
            } catch (error) {}

            if (visible) {
                mfTransportMainStableAt = 0;

                if (
                    mfGetExactVisibleApproachButtons(modal).length > 0
                ) {
                    mfTransportOwnerApproachGoneAt = 0;
                    return false;
                }

                if (!mfTransportOwnerApproachGoneAt) {
                    mfTransportOwnerApproachGoneAt = now;

                    if (mfDebugEnabled) {
                        debugLog(
                            'TRANSPORT MODAL OWNER',
                            `${reason || 'check'} | Approach gone but grey shell still visible. Waiting.`
                        );
                    }
                    return false;
                }

                const emptyFor =
                    now - mfTransportOwnerApproachGoneAt;

                if (emptyFor < MF_TRANSPORT_SHELL_WAIT_MS) {
                    return false;
                }

                if (
                    !mfTransportOwnerCloseAttemptedAt ||
                    now - mfTransportOwnerCloseAttemptedAt > 10000
                ) {
                    const closeButton = modal.querySelector(
                        '.control-btn-container span.lightbox-close[title="Close"], span.lightbox-close[title="Close"], #lightbox_close_inside, button.close'
                    );

                    mfTransportOwnerCloseAttemptedAt = now;

                    if (closeButton) {
                        if (mfDebugEnabled) {
                            debugLog(
                                'TRANSPORT MODAL OWNER',
                                `${reason || 'check'} | Closing stale grey transport shell after ${emptyFor}ms.`
                            );
                        }

                        realClickForQueueRestart(closeButton);
                    }
                }

                return false;
            }
        }

        if (
            lastClickAt > 0 &&
            now - lastClickAt < MF_TRANSPORT_SHELL_WAIT_MS
        ) {
            return false;
        }

        if (!mfTransportMainStableAt) {
            mfTransportMainStableAt = now;

            if (mfDebugEnabled) {
                debugLog(
                    'TRANSPORT MODAL OWNER',
                    `${reason || 'check'} | Shell gone. Starting main-screen settle timer.`
                );
            }
            return false;
        }

        return now - mfTransportMainStableAt >=
            MF_TRANSPORT_MAIN_STABLE_MS;
    }


    function mfIsVisibleInOwnDocument(element) {
        if (!element) return false;

        try {
            const rect = element.getBoundingClientRect();
            const style = element.ownerDocument.defaultView.getComputedStyle(element);

            return rect.width > 0
                && rect.height > 0
                && style.display !== 'none'
                && style.visibility !== 'hidden'
                && style.opacity !== '0';
        } catch (error) {
            try {
                return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
            } catch (innerError) {
                return false;
            }
        }
    }

    function mfGetExactVisibleApproachButtons(scope) {
        if (!scope || !scope.querySelectorAll) return [];

        return Array.from(scope.querySelectorAll(
            'button, a, input[type="button"], input[type="submit"]'
        )).filter(button => {
            if (!mfIsVisibleInOwnDocument(button)) return false;

            const text = [
                button.textContent || '',
                button.value || '',
                button.getAttribute && button.getAttribute('title') || '',
                button.getAttribute && button.getAttribute('aria-label') || ''
            ].join(' ').replace(/\s+/g, ' ').trim().toLowerCase();

            if (text !== 'approach') return false;

            const href = button.getAttribute && (button.getAttribute('href') || '').toLowerCase();

            if (href && href.includes('/missions/')) return false;
            if (button.disabled) return false;
            if (button.getAttribute && button.getAttribute('aria-disabled') === 'true') return false;

            return true;
        });
    }

    function mfGetApproachCapacityInfo(button) {
        const row = button && button.closest ? button.closest('tr') : null;
        const table = row && row.closest ? row.closest('table') : null;

        if (!row) {
            return {
                hasCapacityColumn: false,
                capacity: null,
                rowText: ''
            };
        }

        const rowText = (row.innerText || row.textContent || '')
            .replace(/\s+/g, ' ')
            .trim();

        if (table) {
            const headers = Array.from(table.querySelectorAll('thead th, thead td')).map(header =>
                (header.innerText || header.textContent || '')
                    .replace(/\s+/g, ' ')
                    .trim()
                    .toLowerCase()
            );

            const cells = Array.from(row.children);

            const capacityIndex = headers.findIndex(header =>
                header.includes('free cells') ||
                header.includes('free cell') ||
                header.includes('free beds') ||
                header.includes('free bed') ||
                header === 'free'
            );

            if (capacityIndex >= 0 && cells[capacityIndex]) {
                const capacityText = (cells[capacityIndex].innerText || cells[capacityIndex].textContent || '')
                    .replace(/\s+/g, ' ')
                    .trim();

                const parsed = parseInt((capacityText.match(/-?\d+/) || [])[0], 10);

                return {
                    hasCapacityColumn: true,
                    capacity: Number.isFinite(parsed) ? parsed : 0,
                    rowText
                };
            }
        }

        // MissionChief police/cell rows usually end with:
        // Building | distance | free cells | tax | Approach
        // Example: "GLEN-PS1 83.85 km 10 0% Approach"
        const endMatch = rowText.match(/\b(-?\d+)\s+(-?\d+(?:\.\d+)?)\s*%\s*Approach\s*$/i);

        if (endMatch) {
            return {
                hasCapacityColumn: true,
                capacity: parseInt(endMatch[1], 10) || 0,
                rowText
            };
        }

        return {
            hasCapacityColumn: false,
            capacity: null,
            rowText
        };
    }

    function mfChoosePreferredApproachButton(scope) {
        const buttons = mfGetExactVisibleApproachButtons(scope);

        if (!buttons.length) return null;

        const scopeText = (scope.innerText || scope.textContent || '')
            .replace(/\s+/g, ' ')
            .trim()
            .toLowerCase();

        const prisonerScreen =
            scopeText.includes('release prisoners') ||
            scopeText.includes('free cells') ||
            scopeText.includes('cells:') ||
            scopeText.includes('prisoner');

        const patientScreen =
            scopeText.includes('discharge patient') ||
            scopeText.includes('free beds') ||
            scopeText.includes('hospitals:') ||
            scopeText.includes('hospital distance');

        const inspected = buttons.map(button => ({
            button,
            info: mfGetApproachCapacityInfo(button),
            rowText: (
                button.closest('tr')?.innerText ||
                button.closest('tr')?.textContent ||
                ''
            ).replace(/\s+/g, ' ').trim()
        }));

        const validForScreen = inspected.filter(item => {
            const lowerRow = item.rowText.toLowerCase();

            if (prisonerScreen) {
                if (
                    lowerRow.includes('hospital') ||
                    lowerRow.includes('free beds') ||
                    lowerRow.includes('department')
                ) {
                    return false;
                }
            }

            if (patientScreen && !prisonerScreen) {
                if (
                    lowerRow.includes('police') ||
                    lowerRow.includes('custody') ||
                    lowerRow.includes('free cells')
                ) {
                    return false;
                }
            }

            return true;
        });

        const positive = validForScreen.find(item =>
            item.info.hasCapacityColumn &&
            Number.isFinite(item.info.capacity) &&
            item.info.capacity > 0
        );

        if (positive) {
            if (mfDebugEnabled) {
                debugLog(
                    prisonerScreen ? 'POLICE TRANSPORT' : 'PATIENT TRANSPORT',
                    `Selected Approach with free capacity=${positive.info.capacity} | row="${positive.info.rowText || positive.rowText}"`
                );
            }

            return positive.button;
        }

        const hasCapacityColumns = validForScreen.some(item => item.info.hasCapacityColumn);

        if (hasCapacityColumns) {
            if (mfDebugEnabled) {
                debugLog(
                    prisonerScreen ? 'POLICE TRANSPORT' : 'PATIENT TRANSPORT',
                    `No valid destination with free capacity. Valid rows=${validForScreen.length}.`
                );
            }

            return null;
        }

        // Older transport layouts without a free-capacity column.
        return validForScreen.length ? validForScreen[0].button : null;
    }

    function mfGetTransportModalScore(modal) {
        if (!modal) return -1;

        let score = 0;

        try {
            const style = modal.ownerDocument.defaultView.getComputedStyle(modal);
            const zIndex = parseInt(style.zIndex || '0', 10);
            if (Number.isFinite(zIndex)) score += zIndex * 1000;
        } catch (error) {}

        try {
            const siblings = Array.from(modal.ownerDocument.querySelectorAll('.vm--modal, .modal, .lightbox'));
            score += Math.max(0, siblings.indexOf(modal));
        } catch (error) {}

        return score;
    }

    function mfGetTransportActiveScopes(forceRefresh = false) {
        const now = Date.now();
        const cachedScopes = mfTransportScopeCache.scopes;
        const cacheStillConnected = cachedScopes.every(
            scope => scope?.isConnected !== false
        );

        if (
            !forceRefresh &&
            now < mfTransportScopeCache.expiresAt &&
            cacheStillConnected
        ) {
            return cachedScopes;
        }

        const scopes = buildTransportActiveScopes();

        mfTransportScopeCache = {
            expiresAt: now + 250,
            scopes
        };

        return scopes;
    }

    function buildTransportActiveScopes() {
        const modalCandidates = [];

        mfGetAccessibleDocumentsForTransport().forEach(doc => {
            const modals = Array.from(doc.querySelectorAll('.vm--modal, .modal, .lightbox'));

            modals.forEach(modal => {
                if (!mfIsVisibleInOwnDocument(modal)) return;

                const buttons = mfGetExactVisibleApproachButtons(modal);
                if (!buttons.length) return;

                const text = (modal.innerText || modal.textContent || '')
                    .replace(/\s+/g, ' ')
                    .trim()
                    .toLowerCase();

                const hasTransportContext =
                    !!modal.querySelector('.vehicle-window, .redesign-wrapper[type="vehicle"]') ||
                    text.includes('patient / prisoner handoff') ||
                    text.includes('discharge patient') ||
                    text.includes('release prisoners') ||
                    text.includes('free cells') ||
                    text.includes('free beds') ||
                    text.includes('hospitals:') ||
                    text.includes('cells:');

                if (!hasTransportContext) return;

                modalCandidates.push({
                    scope: modal,
                    score: mfGetTransportModalScore(modal)
                });
            });

            // Direct vehicle page fallback when there is no modal.
            try {
                const path = doc.location && doc.location.pathname || '';

                if (
                    path.startsWith('/vehicles/') &&
                    mfGetExactVisibleApproachButtons(doc.body).length > 0
                ) {
                    modalCandidates.push({
                        scope: doc.body,
                        score: -1
                    });
                }
            } catch (error) {}
        });

        if (!modalCandidates.length) return [];

        modalCandidates.sort((a, b) => b.score - a.score);

        // The current topmost transport screen is the only owner.
        return [modalCandidates[0].scope];
    }

    function mfFindAnyVisibleApproachButtonDeep() {
        const scopes = mfGetTransportActiveScopes();

        for (const scope of scopes) {
            const button = mfChoosePreferredApproachButton(scope);

            if (button) return button;
        }

        return null;
    }

    function mfIsPoliceOrPrisonerTransportActive() {
        const scopes = mfGetTransportActiveScopes();

        return scopes.some(scope => {
            const text = (scope.innerText || scope.textContent || '')
                .replace(/\s+/g, ' ')
                .trim()
                .toLowerCase();

            return (
                mfGetExactVisibleApproachButtons(scope).length > 0 &&
                (
                    text.includes('release prisoners') ||
                    text.includes('free cells') ||
                    text.includes('police cell') ||
                    text.includes('custody') ||
                    text.includes('prisoner')
                )
            );
        });
    }


    function isNextMissionButtonElement(element) {
        if (!element) return false;

        const title = (element.getAttribute && element.getAttribute('title') || '').replace(/\s+/g, ' ').trim().toLowerCase();
        const text = (element.textContent || '').replace(/\s+/g, ' ').trim().toLowerCase();
        const href = (element.getAttribute && element.getAttribute('href') || '').toLowerCase();

        return element.id === 'mission_next_mission_btn' ||
            !!(element.closest && element.closest('#mission_next_mission_btn')) ||
            title.includes('next mission') ||
            text === 'next mission' ||
            href.includes('/missions/mission_next');
    }

    function isInsideCurrentMissionWindow(element) {
        if (!element || !element.closest) return false;

        return !!element.closest(
            '#mission_general_info, #mission_caption, #missionH1, #iframe-inside-container, #mission_content, .mission_content, #lightbox_box, .lightbox, .vm--modal, .modal'
        );
    }

    function getInlinePersonnelQualificationAlertText() {
        const scopes = getCurrentMissionAlertScopes();

        if (!scopes.length) return '';

        const alerts = [];

        scopes.forEach(scope => {
            scope.querySelectorAll('.alert-danger, div[id^="alert_danger_"]').forEach(alert => {
                if (!alerts.includes(alert)) alerts.push(alert);
            });
        });

        for (const alert of alerts) {
            const text = (alert.innerText || alert.textContent || '').replace(/\s+/g, ' ').trim();

            if (!text) continue;

            const lower = text.toLowerCase();

            if (lower.includes('has not enough personal') ||
                lower.includes('not enough personal') ||
                lower.includes('has not enough personnel') ||
                lower.includes('not enough personnel') ||
                lower.includes("doesn't have the right qualification") ||
                lower.includes('does not have the right qualification') ||
                lower.includes('right qualification')) {
                return text;
            }
        }

        return '';
    }

    function isCurrentMissionWindowStillOpenForSafeOpen(reason) {
        const missionInfo = document.querySelector('#mission_general_info');
        const closeInside = document.querySelector('#lightbox_close_inside');
        const insideContainer = document.querySelector('#iframe-inside-container');

        const missionInfoVisible = missionInfo && isVisibleForQueueRestart(missionInfo);
        const closeInsideVisible = closeInside && isVisibleForQueueRestart(closeInside);
        const insideContainerVisible = insideContainer && isVisibleForQueueRestart(insideContainer);
        const personnelAlertText = getInlinePersonnelQualificationAlertText();

        const blocking =
            !!missionInfoVisible ||
            !!closeInsideVisible ||
            (!!insideContainerVisible && !!missionInfo) ||
            !!personnelAlertText;

        if (blocking && mfDebugEnabled) {
            debugLog(
                'SAFE OPEN BLOCK',
                `${reason || 'check'} | missionInfo=${missionInfoVisible ? 'yes' : 'no'} | close=${closeInsideVisible ? 'yes' : 'no'} | inside=${insideContainerVisible ? 'yes' : 'no'} | personnelAlert=${personnelAlertText ? 'yes' : 'no'}`
            );
        }

        if (blocking) {
            try {
                recordIssueEvent('SAFE OPEN BLOCKED', {
                    reason: reason || 'unknown',
                    missionInfoVisible: !!missionInfoVisible,
                    closeInsideVisible: !!closeInsideVisible,
                    insideContainerVisible: !!insideContainerVisible,
                    personnelAlertText: personnelAlertText ? personnelAlertText.slice(0, 350) : ''
                }, true);
            } catch (error) {}
        }

        return blocking;
    }


    function realClickForQueueRestart(element) {
        if (!element) return false;

        try {
            element.scrollIntoView({ block: 'center', inline: 'center' });
        } catch (error) {}

        try {
            element.focus && element.focus({ preventScroll: true });
        } catch (error) {}

        // One native click only.
        // Sending several synthetic click sequences opened duplicate MissionChief modals.
        try {
            if (typeof element.click === 'function') {
                element.click();
                return true;
            }
        } catch (error) {}

        // Final fallback only when native click is unavailable.
        try {
            element.dispatchEvent(new MouseEvent('click', {
                bubbles: true,
                cancelable: true,
                composed: true,
                view: element.ownerDocument?.defaultView || window
            }));
            return true;
        } catch (error) {
            return false;
        }
    }

    function isMissionScreenVisibleForQueueRestart() {
        const missionInfo = document.querySelector('#mission_general_info');
        const closeInside = document.querySelector('#lightbox_close_inside');
        const insideContainer = document.querySelector('#iframe-inside-container');

        const closeInsideVisible = closeInside && isVisibleForQueueRestart(closeInside);
        const insideContainerVisible = insideContainer && isVisibleForQueueRestart(insideContainer);

        if (!missionInfo) {
            return !!closeInsideVisible || !!insideContainerVisible;
        }

        const modal = missionInfo.closest('.vm--modal, .modal, .lightbox');

        if (modal && !isVisibleForQueueRestart(modal)) {
            return !!closeInsideVisible || !!insideContainerVisible || isVisibleForQueueRestart(missionInfo);
        }

        return isVisibleForQueueRestart(missionInfo) || !!modal || !!closeInsideVisible || !!insideContainerVisible;
    }

    function getConfiguredQueueRestartThreshold() {
        const input = document.querySelector(
            '#mf-next-queue-restart-threshold'
        );

        const liveValue = input
            ? parseInt(input.value, 10)
            : NaN;

        if (Number.isFinite(liveValue)) {
            const clamped = Math.max(
                1,
                Math.min(999, liveValue)
            );

            if (clamped !== mfQueueRestartThreshold) {
                mfQueueRestartThreshold = clamped;

                localStorage.setItem(
                    'mf_next_queue_restart_threshold_v10_1_3',
                    String(clamped)
                );
            }
        }

        return mfQueueRestartThreshold;
    }

    function getUnattendedMissionStateForQueueRestart() {
        const button = document.querySelector(
            'a#mission_select_unattended[data-state-filter="unattended"], ' +
            'a#mission_select_unattended[aria-label="Unattended Missions"], ' +
            'a#mission_select_unattended'
        );

        const counter = button
            ? (
                button.querySelector(':scope > span.counter') ||
                button.querySelector('span.counter') ||
                button.querySelector('.counter')
            )
            : null;

        if (!button || !counter) {
            return {
                found: false,
                count: 0,
                text: '',
                reason: button
                    ? 'counter-not-found'
                    : 'unattended-button-not-found'
            };
        }

        const text = (
            counter.innerText ||
            counter.textContent ||
            ''
        ).replace(/\s+/g, ' ').trim();

        const numberMatch = text.match(/\d+/);
        const value = numberMatch
            ? parseInt(numberMatch[0], 10)
            : NaN;

        return {
            found: Number.isFinite(value),
            count: Number.isFinite(value) ? value : 0,
            text,
            reason: Number.isFinite(value)
                ? 'ok'
                : 'counter-not-numeric'
        };
    }

    function getQueueRestartCountState() {
        const unattendedState =
            getUnattendedMissionStateForQueueRestart();

        const threshold =
            getConfiguredQueueRestartThreshold();

        return {
            ...unattendedState,
            threshold,
            reached:
                unattendedState.found &&
                unattendedState.count >= threshold
        };
    }

    function reportQueueRestartCountWait(
        state,
        reason
    ) {
        const statusKey = state.found
            ? `${state.count}/${state.threshold}`
            : `not-found/${state.threshold}`;

        const now = Date.now();

        if (
            statusKey === mfLastQueueThresholdStatusKey &&
            now - mfLastQueueThresholdStatusAt < 3000
        ) {
            return;
        }

        mfLastQueueThresholdStatusKey = statusKey;
        mfLastQueueThresholdStatusAt = now;

        if (state.found) {
            updateStatusBox(
                `Waiting for unattended missions: ${state.count}/${state.threshold}.`
            );
        } else {
            updateStatusBox(
                `Waiting for unattended mission counter (${state.threshold} required).`
            );
        }

        if (mfDebugEnabled) {
            debugLog(
                'QUEUE COUNT GATE',
                `${reason || 'check'} | found=${state.found ? 'yes' : 'no'} | count=${state.found ? state.count : 'n/a'} | threshold=${state.threshold} | reached=${state.reached ? 'yes' : 'no'} | selector=#mission_select_unattended > span.counter`
            );
        }
    }

    function getVisibleMissionCloseButtonsForQueueRestart() {
        // V10.1.5:
        // Use the exact MissionChief modal close target confirmed from the live HTML:
        // <div class="control-btn-container"><span title="Close" class="lightbox-close">...</span></div>
        // Keep this narrow so we do not click old/hidden close buttons.
        const exactSelectors = [
            '.vm--modal .control-btn-container span.lightbox-close[title="Close"]',
            '.vm--modal .control-btn-container .lightbox-close[title="Close"]',
            '.control-btn-container span.lightbox-close[title="Close"]',
            '.control-btn-container .lightbox-close[title="Close"]'
        ];

        for (const selector of exactSelectors) {
            const matches = Array.from(document.querySelectorAll(selector)).filter(button => {
                if (!button) return false;
                if (button.id && button.id.includes('mf-')) return false;

                const modal = button.closest('.vm--modal, .modal, .lightbox');
                const container = button.closest('.control-btn-container');

                return !!container && (
                    isVisibleForQueueRestart(button) ||
                    isVisibleForQueueRestart(container) ||
                    (modal && isVisibleForQueueRestart(modal))
                );
            });

            if (matches.length > 0) {
                return matches;
            }
        }

        return [];
    }


    function sendEscapeForQueueRestart() {
        ['keydown', 'keyup'].forEach(type => {
            try {
                document.dispatchEvent(new KeyboardEvent(type, {
                    key: 'Escape',
                    code: 'Escape',
                    keyCode: 27,
                    which: 27,
                    bubbles: true,
                    cancelable: true
                }));
            } catch (error) {}
        });
    }

    async function closeMissionScreenForQueueRestart() {
        // Do not close the vehicle transport screen while an Approach button is visible.
        // The transport watcher must click Approach first; MissionChief will auto-close after the last Approach.
        if (typeof mfIsApproachTransportVisible === 'function' && mfIsApproachTransportVisible()) {
            if (mfDebugEnabled) {
                debugLog('TRANSPORT SEQUENCE', 'Close blocked because visible Approach button is present.');
            }

            return false;
        }

        let clicked = false;

        for (let attempt = 1; attempt <= 6; attempt++) {
            if (!isMissionScreenVisibleForQueueRestart()) {
                return clicked;
            }

            const closeButtons = getVisibleMissionCloseButtonsForQueueRestart();

            if (!closeButtons.length) {
                if (mfDebugEnabled) {
                    debugLog('NEXT QUEUE', `Close attempt ${attempt}: close button not found. Sending Escape.`);
                }

                sendEscapeForQueueRestart();
                await wait(650);
                continue;
            }

            for (const closeButton of closeButtons.slice(0, 2)) {
                clicked = true;

                if (mfDebugEnabled) {
                    const title = closeButton.getAttribute('title') || '';
                    const cls = closeButton.className || '';
                    const tag = closeButton.tagName || '';
                    const inModal = closeButton.closest('.vm--modal') ? 'yes' : 'no';
                    debugLog('NEXT QUEUE', `Close attempt ${attempt}: clicking exact ${tag}.${String(cls).replace(/\s+/g, '.')} title="${title}" inModal=${inModal}.`);
                }

                // Click the confirmed span target only.
                realClickForQueueRestart(closeButton);

                await wait(500);

                if (!isMissionScreenVisibleForQueueRestart()) {
                    return clicked;
                }
            }

            await wait(550);
        }

        return clicked;
    }


    function findFirstMissionButtonForQueueRestart() {
        if (isCurrentMissionWindowStillOpenForSafeOpen('find-first-mission')) return null;

        const candidates = Array.from(document.querySelectorAll(
            'a.mission-alarm-button[id^="alarm_button_"][href*="/missions/"], ' +
            'a.lightbox-open.mission-alarm-button[id^="alarm_button_"][href*="/missions/"]'
        ));

        return candidates.find(anchor => {
            const href = anchor.getAttribute('href') || '';
            const text = (anchor.textContent || '')
                .replace(/\s+/g, ' ')
                .trim()
                .toLowerCase();

            const disabled =
                anchor.classList.contains('disabled') ||
                anchor.hasAttribute('disabled') ||
                anchor.getAttribute('aria-disabled') === 'true';

            if (disabled) return false;
            if (isNextMissionButtonElement(anchor)) return false;
            if (isInsideCurrentMissionWindow(anchor)) return false;
            if (!/^\/missions\/\d+/.test(href)) return false;
            if (!isVisibleForQueueRestart(anchor)) return false;

            return (
                anchor.id.startsWith('alarm_button_') &&
                (
                    text === 'dispatch' ||
                    text.includes('dispatch') ||
                    anchor.classList.contains('mission-alarm-button')
                )
            );
        }) || null;
    }

    function clickUnattendedMissionFilterForQueueRestart() {
        const button = document.querySelector('#mission_select_unattended');

        if (!button) return false;

        const alreadyActive =
            button.classList.contains('btn-success') &&
            !button.classList.contains('btn-danger');

        if (alreadyActive) {
            if (mfDebugEnabled) {
                debugLog('SILENT QUEUE', 'Unattended filter is already active; not clicking it again.');
            }

            return true;
        }

        return realClickForQueueRestart(button);
    }

    function isTransportScreenBlockingQueueRestart() {
        if (mfFindAnyVisibleApproachButtonDeep()) return true;

        const scopes = mfGetTransportActiveScopes();

        return scopes.length > 0;
    }


    function getButtonTextForTransport(element) {
        if (!element) return '';

        return [
            element.textContent || '',
            element.getAttribute('title') || '',
            element.getAttribute('value') || '',
            element.getAttribute('aria-label') || ''
        ].join(' ').replace(/\s+/g, ' ').trim().toLowerCase();
    }

    function isBadTransportButtonCandidate(element) {
        const text = getButtonTextForTransport(element);
        const id = (element.id || '').toLowerCase();
        const href = (element.getAttribute('href') || '').toLowerCase();

        if (!text && !id && !href) return true;

        if (id === 'mission_next_mission_btn') return true;
        if (href.includes('/missions/')) return true;
        if (text.includes('next mission')) return true;
        if (text.includes('unit finder')) return true;
        if (text.includes('dispatch')) return true;
        if (text.includes('close')) return true;
        if (text.includes('cancel')) return true;
        if (text.includes('back')) return true;
        if (text.includes('load missing')) return true;

        return false;
    }

    function scoreTransportButtonCandidate(element) {
        const text = getButtonTextForTransport(element);
        const cls = (element.className || '').toString().toLowerCase();

        let score = 0;

        if (text === 'approach') score += 100;
        if (text.includes('approach')) score += 90;
        if (text.includes('transport')) score += 70;
        if (text.includes('send')) score += 50;

        if (cls.includes('btn-success')) score += 25;
        if (cls.includes('btn-primary')) score += 15;
        if (cls.includes('btn')) score += 5;

        // Prefer buttons inside rows/cards that mention hospital/cell/patient/prisoner.
        const container = element.closest('tr, li, .panel, .card, .well, .modal-body, div');
        const containerText = container ? (container.innerText || '').replace(/\s+/g, ' ').trim().toLowerCase() : '';

        if (containerText.includes('hospital')) score += 10;
        if (containerText.includes('police cell')) score += 10;
        if (containerText.includes('cell')) score += 5;
        if (containerText.includes('patient')) score += 5;
        if (containerText.includes('prisoner')) score += 5;

        return score;
    }


    function findExactFirstApproachTransportButton() {
        const deepButton = mfFindAnyVisibleApproachButtonDeep();

        if (deepButton) return deepButton;

        const scopes = Array.from(document.querySelectorAll(
            '.vm--modal, .modal, .lightbox, .vehicle-window, .redesign-wrapper[type="vehicle"]'
        )).filter(element => {
            try {
                return isElementVisible(element);
            } catch (error) {
                return false;
            }
        });

        for (const scope of scopes) {
            const button = mfChoosePreferredApproachButton(scope);

            if (button) return button;
        }

        return null;
    }


    function getTransportScreenFingerprint() {
        const modal = document.querySelector('.vm--modal');
        const h1 = modal ? (modal.querySelector('h1')?.innerText || '') : '';
        const missionLink = modal ? (modal.querySelector('a[href*="/missions/"]')?.getAttribute('href') || '') : '';
        const firstApproach = findExactFirstApproachTransportButton();
        const rowText = firstApproach && firstApproach.closest('tr')
            ? (firstApproach.closest('tr').innerText || '').replace(/\s+/g, ' ').trim()
            : '';

        return `${h1}|${missionLink}|${rowText}`;
    }



    function isVehicleTransportModalVisible() {
        if (mfFindAnyVisibleApproachButtonDeep()) return true;

        const modal = document.querySelector('.vm--modal');
        if (!modal || !isElementVisible(modal)) return false;

        const modalText = (modal.innerText || '').replace(/\s+/g, ' ').trim().toLowerCase();

        return (
            !!modal.querySelector('.vehicle-window, .redesign-wrapper[type="vehicle"]') ||
            modalText.includes('approach') ||
            modalText.includes('prisoner') ||
            modalText.includes('police cell') ||
            modalText.includes('cell') ||
            modalText.includes('custody')
        ) && (
            modalText.includes('patient / prisoner handoff') ||
            modalText.includes('hospital') ||
            modalText.includes('free beds') ||
            modalText.includes('approach') ||
            modalText.includes('prisoner') ||
            modalText.includes('police cell') ||
            modalText.includes('cell') ||
            modalText.includes('custody')
        );
    }


    function isAnyTransportModalOrApproachVisible() {
        return !!(
            findExactFirstApproachTransportButton() ||
            (typeof mfBruteFindFirstApproachButton === 'function' && mfBruteFindFirstApproachButton()) ||
            (typeof mfBruteFindVehicleTransportModal === 'function' && mfBruteFindVehicleTransportModal()) ||
            (typeof isVehicleTransportModalVisible === 'function' && isVehicleTransportModalVisible())
        );
    }

    function markTransportSequenceActive() {
        mfTransportSequenceActive = true;
        sessionStorage.setItem('mf_transport_sequence_active_v1', 'true');
        sessionStorage.setItem('mf_post_transport_rehook_pending_v1', 'true');
        localStorage.setItem('mf_post_transport_rehook_pending_v1', 'true');
        localStorage.setItem('mf_auto_mode_running', 'true');

        const rehookUntil = Date.now() + 120000;
        sessionStorage.setItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY, String(rehookUntil));
        localStorage.setItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY, String(rehookUntil));
    }

    function clearTransportSequenceActive() {
        mfTransportSequenceActive = false;
        sessionStorage.removeItem('mf_transport_sequence_active_v1');
        sessionStorage.removeItem('mf_brute_transport_sent_v1');
        sessionStorage.removeItem('mf_transport_sent_in_vehicle_modal_v1');
    }

    function clearPostTransportRehookPending() {
        clearTransportSequenceActive();
        sessionStorage.removeItem('mf_post_transport_rehook_pending_v1');
        localStorage.removeItem('mf_post_transport_rehook_pending_v1');
        mfClearTransportOwner('post-transport complete');
    }

    function isRecentTransportRehookWindowActive() {
        if (isManualAutoStopActive()) return false;

        const until = Math.max(
            parseInt(sessionStorage.getItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY) || '0', 10) || 0,
            parseInt(localStorage.getItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY) || '0', 10) || 0
        );

        if (until > Date.now()) return true;

        sessionStorage.removeItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY);
        localStorage.removeItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY);
        return false;
    }

    function isPostTransportRehookPending() {
        if (isManualAutoStopActive()) return false;

        return sessionStorage.getItem('mf_post_transport_rehook_pending_v1') === 'true' ||
            localStorage.getItem('mf_post_transport_rehook_pending_v1') === 'true' ||
            wasTransportSequenceActive() ||
            isRecentTransportRehookWindowActive();
    }

    function isAutoModeActiveFlagSet() {
        if (isManualAutoStopActive()) return false;

        return autoModeRunning === true ||
            sessionStorage.getItem('mf_auto_mode_running') === 'true' ||
            localStorage.getItem('mf_auto_mode_running') === 'true';
    }

    function isTransportAutomationAllowed() {
        if (isManualAutoStopActive()) return false;

        // Transport/re-hook helpers must only run while Auto Mode is actually on,
        // or while a transport re-hook is genuinely pending after Auto Mode created it.
        return isAutoModeActiveFlagSet() || isPostTransportRehookPending();
    }

    function clearAllTransportAutomationFlags(reason) {
        mfTransportSequenceActive = false;
        mfTransportContinuationRunning = false;
        mfPostTransportOpening = false;
        mfGlobalTransportClicking = false;
        mfBruteApproachClicking = false;
        mfTransportApproachClicking = false;

        sessionStorage.removeItem('mf_transport_sequence_active_v1');
        sessionStorage.removeItem('mf_post_transport_rehook_pending_v1');
        sessionStorage.removeItem('mf_brute_transport_sent_v1');
        sessionStorage.removeItem('mf_transport_sent_in_vehicle_modal_v1');
        localStorage.removeItem('mf_post_transport_rehook_pending_v1');
        sessionStorage.removeItem(MF_TRANSPORT_CLICK_LOCK_UNTIL_KEY);
        sessionStorage.removeItem(MF_TRANSPORT_LAST_CLICK_AT_KEY);
        sessionStorage.removeItem(MF_TRANSPORT_LAST_CLICK_REASON_KEY);
        mfClearTransportOwner(reason || 'transport flags cleared');

        const clearRecentRehook =
            String(reason || '').toLowerCase().includes('manual') ||
            String(reason || '').toLowerCase().includes('stopped');

        if (clearRecentRehook) {
            sessionStorage.removeItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY);
            localStorage.removeItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY);
        }

        if (mfDebugEnabled) {
            debugLog('AUTO GUARD', `Cleared all transport automation flags. reason=${reason || 'unknown'}`);
        }
    }

    function hasVisibleApproachButtonForTransportRehook() {
        return !!(
            (typeof mfFindAnyVisibleApproachButtonDeep === 'function' && mfFindAnyVisibleApproachButtonDeep()) ||
            (typeof mfFindAnyVisibleApproachButtonInModal === 'function' && mfFindAnyVisibleApproachButtonInModal())
        );
    }

    function forceAutoModeBackOnForTransportRehook() {
        if (isManualAutoStopActive()) {
            if (mfDebugEnabled) {
                debugLog('AUTO STOP GUARD', 'Blocked forceAutoModeBackOnForTransportRehook because Auto Mode was manually stopped.');
            }

            return false;
        }

        autoModeRunning = true;
        autoModeLoopActive = false;
        sessionStorage.setItem('mf_auto_mode_running', 'true');
        localStorage.setItem('mf_auto_mode_running', 'true');

        return true;
    }

    function findAnyMainScreenMissionOpenButton() {
        // Exact mission Dispatch buttons only.
        // Generic lightbox links caused building/vehicle screens to be opened.
        return findFirstMissionButtonForQueueRestart();
    }

    async function hardOpenFirstMissionFromMainAfterTransport(reason) {
        if (!MF_IS_TOP_WINDOW) return false;
        if (isManualAutoStopActive()) return false;
        if (!isTransportAutomationAllowed()) return false;
        if (!mfTransportShellReadyForRehook(`hard-${reason}`)) return false;

        if (!acquireTransportRehookLock(`hard-rehook-${reason}`, 28000)) return false;

        try {
            // During the first few seconds after the final Approach click,
            // MissionChief may still be closing/refreshing the vehicle screen.
            // Do not clear the pending rehook if this blocks; just retry later.
            if (shouldBlockOpeningNewMissionForTransport(`hard-rehook-${reason}`)) {
                return false;
            }

            if (isCurrentMissionWindowStillOpenForSafeOpen(`hard-rehook-${reason}`)) {
                if (mfDebugEnabled) {
                    debugLog('TRANSPORT REHOOK', `${reason}: mission window still open; waiting for next rehook tick.`);
                }
                return false;
            }

            if (!forceAutoModeBackOnForTransportRehook()) return false;

            if (mfDebugEnabled) {
                debugLog('TRANSPORT REHOOK', `${reason}: hard main-screen open attempt started.`);
            }

            // If we are still on a vehicle URL after transport closes, do a real page load
            // back to the main screen. history.pushState only changes the URL and leaves the
            // vehicle DOM in place, which prevents mission-count/open from working.
            if (window.location.pathname.startsWith('/vehicles/')) {
                if (mfDebugEnabled) {
                    debugLog('TRANSPORT REHOOK', `${reason}: on vehicle page after transport, loading main page for mission count.`);
                }

                sessionStorage.setItem('mf_post_transport_rehook_pending_v1', 'true');
                localStorage.setItem('mf_post_transport_rehook_pending_v1', 'true');
                const rehookUntil = Date.now() + 120000;
                sessionStorage.setItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY, String(rehookUntil));
                localStorage.setItem(MF_TRANSPORT_REHOOK_RECENT_UNTIL_KEY, String(rehookUntil));

                window.location.href = '/';
                return false;
            }

            const started = Date.now();
            let filterClickedAt = 0;

            while (Date.now() - started < 120000) {
                if (isManualAutoStopActive()) return false;

                if (!mfTransportShellReadyForRehook(`hard-loop-${reason}`)) {
                    await wait(800);
                    continue;
                }

                if (hasVisibleApproachButtonForTransportRehook()) {
                    if (mfDebugEnabled) {
                        debugLog('TRANSPORT REHOOK', `${reason}: Approach visible again; pausing rehook.`);
                    }
                    return false;
                }

                if (isCurrentMissionWindowStillOpenForSafeOpen(`hard-rehook-${reason}`)) {
                    if (mfDebugEnabled) {
                        debugLog('TRANSPORT REHOOK', `${reason}: current mission window still open; retrying shortly.`);
                    }
                    await wait(1000);
                    continue;
                }

                // If a mission modal/page is already open again, just restart Auto Mode.
                if (isMissionPage() && isMissionScreenVisibleForQueueRestart()) {
                    clearPostTransportRehookPending();

                    if (mfDebugEnabled) {
                        debugLog('TRANSPORT REHOOK', `${reason}: mission modal visible; restarting Auto Mode.`);
                    }

                    forceAutoModeBackOnForTransportRehook();

                    setTimeout(() => {
                        if (autoModeRunning && !autoModeLoopActive) runAutoModeLoop();
                    }, 1000);

                    return true;
                }

                if (hasVisibleQueueOpenModal(`hard-rehook-${reason}`)) {
                    await wait(800);
                    continue;
                }

                const queueCountState =
                    getQueueRestartCountState();

                if (!queueCountState.reached) {
                    reportQueueRestartCountWait(
                        queueCountState,
                        `transport-rehook-${reason}`
                    );

                    await wait(1200);
                    continue;
                }

                if (
                    !filterClickedAt ||
                    Date.now() - filterClickedAt > 5000
                ) {
                    clickUnattendedMissionFilterForQueueRestart();
                    filterClickedAt = Date.now();

                    if (mfDebugEnabled) {
                        debugLog(
                            'TRANSPORT REHOOK',
                            `${reason}: threshold reached ${queueCountState.count}/${queueCountState.threshold}; unattended filter ready.`
                        );
                    }
                }

                await wait(900);

                // The counter can change while MissionChief rebuilds the
                // filtered list, so verify it once more before Dispatch.
                const confirmedQueueCountState =
                    getQueueRestartCountState();

                if (!confirmedQueueCountState.reached) {
                    reportQueueRestartCountWait(
                        confirmedQueueCountState,
                        `transport-rehook-after-filter-${reason}`
                    );

                    await wait(1200);
                    continue;
                }

                let firstMissionButton = findFirstMissionButtonForQueueRestart();

                if (!firstMissionButton) {
                    firstMissionButton = findAnyMainScreenMissionOpenButton();
                }

                if (firstMissionButton) {
                    const href = firstMissionButton.getAttribute('href') || firstMissionButton.href || '';

                    if (mfDebugEnabled) {
                        debugLog('TRANSPORT REHOOK', `${reason}: opening first mission via hard rehook: ${href || 'unknown href'}`);
                    }

                    try {
                        updateStatusBox('Transport complete. Opening first mission from main screen...');
                    } catch (error) {}

                    if (!acquireMainMissionOpenLock(`transport-rehook-${reason}`, 24000)) {
                        await wait(1000);
                        continue;
                    }

                    const targetMissionId =
                        parseMissionIdFromHrefForQueueRestart(href);

                    const previousMissionId =
                        getCurrentMissionIdForQueueRestart();

                    const modalCountBeforeClick =
                        getVisibleQueueOpenModals().length;

                    if (modalCountBeforeClick > 0) {
                        releaseMainMissionOpenLock(
                            `transport-rehook-${reason}-modal-already-open`
                        );
                        return false;
                    }

                    sessionStorage.removeItem(MF_QUEUE_WAIT_ACTIVE_FLAG);
                    sessionStorage.removeItem(MF_FINAL_QUEUE_DISPATCH_FLAG);
                    mfQueueRestartWaiting = false;

                    markMainMissionOpeningPending(
                        targetMissionId,
                        `transport-rehook-${reason}`,
                        45000
                    );

                    const clicked =
                        realClickForQueueRestart(firstMissionButton);

                    if (!clicked) {
                        clearMainMissionOpeningPending(
                            `transport-rehook-${reason}-click-failed`
                        );
                        return false;
                    }

                    const opened =
                        await waitForSpecificQueueMissionToOpen(
                            targetMissionId,
                            previousMissionId,
                            modalCountBeforeClick
                        );

                    if (opened || hasVisibleQueueOpenModal(
                        `transport-rehook-${reason}-after-click`
                    )) {
                        clearMainMissionOpeningPending(
                            `transport-rehook-${reason}-opened`
                        );
                        clearPostTransportRehookPending();

                        forceAutoModeBackOnForTransportRehook();

                        await resumeAutoAfterMainMissionOpen(
                            `transport-rehook-${reason}`
                        );

                        return true;
                    }

                    clearMainMissionOpeningPending(
                        `transport-rehook-${reason}-not-confirmed`
                    );

                    if (mfDebugEnabled) {
                        debugLog(
                            'TRANSPORT REHOOK',
                            `${reason}: mission open not confirmed and no loading modal exists.`
                        );
                    }

                    return false;
                }

                await wait(1000);
            }

            if (mfDebugEnabled) {
                debugLog('TRANSPORT REHOOK', `${reason}: hard main-screen rehook timed out.`);
            }

            return false;
        } finally {
            releaseTransportRehookLock(`hard-rehook-${reason}-finally`);
        }
    }

    function wasTransportSequenceActive() {
        return mfTransportSequenceActive ||
            sessionStorage.getItem('mf_transport_sequence_active_v1') === 'true' ||
            sessionStorage.getItem('mf_brute_transport_sent_v1') === 'true' ||
            sessionStorage.getItem('mf_transport_sent_in_vehicle_modal_v1') === 'true';
    }

    async function openFirstMissionAfterTransportAutoClose(reason) {
        if (!MF_IS_TOP_WINDOW) return false;
        if (isManualAutoStopActive()) return false;
        if (!isTransportAutomationAllowed()) return false;

        if (isTransportRehookLockActive(`open-after-transport-${reason}`)) {
            return false;
        }

        if (mfTransportContinuationRunning || mfPostTransportOpening) {
            return false;
        }

        if (!isPostTransportRehookPending()) return false;
        if (hasVisibleApproachButtonForTransportRehook()) return false;
        if (!mfTransportShellReadyForRehook(reason)) return false;

        mfTransportContinuationRunning = true;
        mfPostTransportOpening = true;

        try {
            forceAutoModeBackOnForTransportRehook();

            if (mfDebugEnabled) {
                debugLog(
                    'TRANSPORT REHOOK',
                    `${reason}: old transport shell gone; starting one rehook.`
                );
            }

            updateStatusBox(
                'Transport complete. Main screen stable; opening one mission...'
            );

            if (
                isMissionPage() &&
                isMissionScreenVisibleForQueueRestart()
            ) {
                clearPostTransportRehookPending();

                setTimeout(() => {
                    forceAutoModeBackOnForTransportRehook();
                    if (!autoModeLoopActive) runAutoModeLoop();
                }, 1000);

                return true;
            }

            return await hardOpenFirstMissionFromMainAfterTransport(reason);
        } finally {
            mfTransportContinuationRunning = false;
            mfPostTransportOpening = false;
        }
    }



    function startPostTransportRehookWatcher() {
        if (!MF_IS_TOP_WINDOW) return;
        if (mfPostTransportRehookTimer) return;

        mfPostTransportRehookTimer = setInterval(async () => {
            if (isManualAutoStopActive()) return;
            if (!isTransportAutomationAllowed()) return;
            if (!isPostTransportRehookPending()) return;
            if (mfPostTransportOpening || mfTransportContinuationRunning) return;
            if (isMainMissionOpeningPending('post-transport-watch')) return;
            if (hasVisibleApproachButtonForTransportRehook()) return;

            await openFirstMissionAfterTransportAutoClose(
                'post-transport-watch'
            );
        }, 1200);
    }



    function closeVehicleTransportModalIfDone(reason) {
        return false;
    }


    async function clickExactApproachTransportButton(reason) {
        if (isManualAutoStopActive()) return false;
        if (!isTransportAutomationAllowed()) return false;
        if (mfGlobalTransportClicking) return false;
        if (mfTransportApproachClicking) return false;
        if (Date.now() - mfTransportLastClickAt < 4000) return false;

        const button = findExactFirstApproachTransportButton();

        if (!button) return false;

        if (!mfAcquireSharedTransportClick(
            `exact-${reason || 'unknown'}`
        )) {
            return false;
        }

        mfMarkTransportOwner(
            button,
            `exact-${reason || 'unknown'}`
        );

        const activeScopes = mfGetTransportActiveScopes();

        if (
            activeScopes.length &&
            !activeScopes[0].contains(button) &&
            activeScopes[0] !== button.ownerDocument.body
        ) {
            if (mfDebugEnabled) {
                debugLog('GLOBAL TRANSPORT', 'Blocked stale Approach button from a background transport modal.');
            }

            return false;
        }

        const fingerprint = getTransportScreenFingerprint();
        const now = Date.now();

        // Four seconds between Approach clicks.
        if (fingerprint && fingerprint === mfLastTransportFingerprint && now - mfLastTransportClickAt < 4000) {
            return false;
        }

        mfGlobalTransportClicking = true;
        mfTransportApproachClicking = true;
        mfLastTransportFingerprint = fingerprint || '';
        mfLastTransportClickAt = now;
        mfTransportLastClickAt = now;
        markTransportSequenceActive();

        try {
            const row = button.closest('tr');
            const rowText = row ? (row.innerText || '').replace(/\s+/g, ' ').trim() : '';
            const text = (button.textContent || 'Approach').replace(/\s+/g, ' ').trim();

            if (mfDebugEnabled) {
                debugLog('GLOBAL TRANSPORT', `${reason}: clicking "${text}" | row="${rowText}"`);
            }

            try {
                updateStatusBox(`Transport handoff: clicking ${text}...`);
            } catch (error) {}

            sessionStorage.setItem('mf_transport_sent_in_vehicle_modal_v1', 'true');
            realClickForQueueRestart(button);

            await wait(4000);

            return true;
        } finally {
            mfGlobalTransportClicking = false;
            mfTransportApproachClicking = false;
        }
    }


    function isAutoModeSessionActiveForTransportWatcher() {
        return isTransportAutomationAllowed();
    }

    function startGlobalTransportApproachWatcher() {
        // Dedicated post-transport watcher owns the rehook.
        return;
    }




    function mfBruteNormaliseText(value) {
        return String(value || '').replace(/\s+/g, ' ').trim();
    }


    function mfFindAnyVisibleApproachButtonInModal() {
        const deepButton = mfFindAnyVisibleApproachButtonDeep();

        if (deepButton) return deepButton;

        const modals = Array.from(document.querySelectorAll(
            '.vm--modal, .modal, .lightbox, .vehicle-window, .redesign-wrapper[type="vehicle"]'
        )).filter(modal => {
            try {
                return mfIsVisibleInOwnDocument(modal);
            } catch (error) {
                return false;
            }
        });

        for (const modal of modals) {
            const button = mfChoosePreferredApproachButton(modal);

            if (button) return button;
        }

        return null;
    }

    function mfIsApproachTransportVisible() {
        return !!mfFindAnyVisibleApproachButtonInModal();
    }


    function mfBruteFindVehicleTransportModal() {
        const simpleButton = mfFindAnyVisibleApproachButtonInModal();

        if (simpleButton) {
            return simpleButton.closest('.vm--modal, .modal, .lightbox, .vehicle-window, body') || null;
        }

        const scopes = mfGetTransportActiveScopes();

        if (scopes.length) {
            return scopes[0];
        }

        const modals = Array.from(document.querySelectorAll('.vm--modal'));

        for (const modal of modals) {
            const modalText = mfBruteNormaliseText(modal.innerText).toLowerCase();

            const hasVehicleWindow = !!modal.querySelector('.vehicle-window, .redesign-wrapper[type="vehicle"]');
            const hasTransportWords =
                modalText.includes('hospital') ||
                modalText.includes('free beds') ||
                modalText.includes('patient') ||
                modalText.includes('handoff') ||
                modalText.includes('prisoner') ||
                modalText.includes('police cell') ||
                modalText.includes('cell') ||
                modalText.includes('custody') ||
                modalText.includes('transport');

            if ((hasVehicleWindow && hasTransportWords) || modalText.includes('approach')) {
                return modal;
            }
        }

        return null;
    }


    function mfBruteFindFirstApproachButton() {
        // This helper already performs the deep transport-scope lookup, so do
        // not run the same deep scan once before calling it.
        const simpleButton = mfFindAnyVisibleApproachButtonInModal();

        if (simpleButton) return simpleButton;

        const modal = mfBruteFindVehicleTransportModal();

        if (!modal) return null;

        // First preference: first Approach button in the hospital rows.
        const rowButtons = Array.from(
            modal.querySelectorAll(
                'table tbody tr button.btn.btn-success, ' +
                'table tbody tr button.btn-success'
            )
        );

        for (const button of rowButtons) {
            const text = mfBruteNormaliseText(button.textContent).toLowerCase();

            if (text === 'approach') {
                return button;
            }
        }

        // Fallback: first exact green Approach button anywhere inside the vehicle modal.
        const buttons = Array.from(
            modal.querySelectorAll(
                'button.btn.btn-success, button.btn-success'
            )
        );

        for (const button of buttons) {
            const text = mfBruteNormaliseText(button.textContent).toLowerCase();

            if (text === 'approach') {
                return button;
            }
        }

        return null;
    }

    function mfBruteTransportFingerprint(button) {
        if (!button) return '';

        const modal = button.closest('.vm--modal');
        const row = button.closest('tr');

        const title = modal ? mfBruteNormaliseText(modal.querySelector('h1')?.innerText || '') : '';
        const currentMission = modal ? mfBruteNormaliseText(modal.querySelector('a[href*="/missions/"]')?.innerText || '') : '';
        const rowText = row ? mfBruteNormaliseText(row.innerText) : mfBruteNormaliseText(button.textContent);

        return `${title}|${currentMission}|${rowText}`;
    }

    function mfBruteClickElement(element) {
        if (!element) return false;

        try {
            element.scrollIntoView({ block: 'center', inline: 'center' });
        } catch (error) {}

        try {
            element.focus && element.focus({ preventScroll: true });
        } catch (error) {}

        // For Vue buttons, the native click is normally the safest.
        try {
            element.click();
            return true;
        } catch (error) {}

        try {
            const rect = element.getBoundingClientRect();
            const x = rect.left + Math.max(1, rect.width / 2);
            const y = rect.top + Math.max(1, rect.height / 2);

            for (const eventName of ['mousedown', 'mouseup', 'click']) {
                const event = new MouseEvent(eventName, {
                    bubbles: true,
                    cancelable: true,
                    view: window,
                    clientX: x,
                    clientY: y
                });

                element.dispatchEvent(event);
            }

            return true;
        } catch (error) {
            return false;
        }
    }


    function mfBruteCloseTransportModalIfDone() {
        return false;
    }


    async function mfBruteClickFirstApproach(reason) {
        if (!isTransportAutomationAllowed()) return false;
        if (mfBruteApproachClicking) return false;
        if (mfTransportApproachClicking) return false;
        if (Date.now() - mfTransportLastClickAt < 4000) return false;

        const button = mfBruteFindFirstApproachButton();

        if (!button) return false;

        if (!mfAcquireSharedTransportClick(
            `brute-${reason || 'unknown'}`
        )) {
            return false;
        }

        mfMarkTransportOwner(
            button,
            `brute-${reason || 'unknown'}`
        );

        const activeScopes = mfGetTransportActiveScopes();

        if (
            activeScopes.length &&
            !activeScopes[0].contains(button) &&
            activeScopes[0] !== button.ownerDocument.body
        ) {
            if (mfDebugEnabled) {
                debugLog('TRANSPORT APPROACH', 'Blocked stale Approach button from a background transport modal.');
            }

            return false;
        }

        const now = Date.now();

        mfBruteApproachClicking = true;
        mfTransportApproachClicking = true;
        mfBruteLastFingerprint = mfBruteTransportFingerprint(button) || '';
        mfBruteLastClickAt = now;
        mfTransportLastClickAt = now;
        markTransportSequenceActive();

        try {
            const row = button.closest('tr');
            const rowText = row ? mfBruteNormaliseText(row.innerText) : '';
            const buttonText = mfBruteNormaliseText(button.textContent);

            const capacityInfo = mfGetApproachCapacityInfo(button);

            try {
                updateStatusBox(
                    capacityInfo.hasCapacityColumn
                        ? `Transport handoff: clicking Approach with ${capacityInfo.capacity} free place(s)...`
                        : 'Transport handoff: clicking first Approach...'
                );
            } catch (error) {}

            if (mfDebugEnabled) {
                debugLog(
                    'TRANSPORT APPROACH',
                    `chosenCapacity=${capacityInfo.hasCapacityColumn ? capacityInfo.capacity : 'n/a'} | row="${capacityInfo.rowText || rowText}"`
                );
            }

            sessionStorage.setItem('mf_brute_transport_sent_v1', 'true');

            const clicked = mfBruteClickElement(button);

            await wait(4000);

            return clicked;
        } finally {
            mfBruteApproachClicking = false;
            mfTransportApproachClicking = false;
        }
    }


    function startBruteApproachTransportWatcher() {
        if (!MF_IS_TOP_WINDOW) return;
        if (mfBruteApproachWatcherTimer) return;

        mfBruteApproachWatcherTimer = setInterval(async () => {
            if (isManualAutoStopActive()) return;

            // Auto guard: this must not run when Auto Mode is off,
            // unless a valid post-transport rehook is pending from an Auto Mode run.
            if (!isTransportAutomationAllowed()) return;

            // Most Auto Mode ticks are normal missions, not transport screens.
            // A cheap preflight avoids full modal/body scans until a vehicle
            // transport surface or exact Approach button actually exists.
            if (!mfHasPotentialTransportUi()) return;

            const button = mfBruteFindFirstApproachButton();

            if (button) {
                await mfBruteClickFirstApproach('global-brute-watch');
                return;
            }

            // Dedicated post-transport watcher owns the rehook.
        }, 1000);
    }



    function findTransportSendButton() {
        // The new MissionChief transport screen is a vehicle modal with hospital rows.
        // The correct action is the first visible green "Approach" button in that table.
        const exactApproachButton = findExactFirstApproachTransportButton();

        if (exactApproachButton) {
            return exactApproachButton;
        }

        // Fallback for older transport screens.
        const candidates = Array.from(document.querySelectorAll('button, a, input[type="button"], input[type="submit"]'))
            .filter(element => isElementVisible(element))
            .filter(element => !isBadTransportButtonCandidate(element))
            .map(element => ({
                element,
                score: scoreTransportButtonCandidate(element)
            }))
            .filter(item => item.score > 0)
            .sort((a, b) => b.score - a.score);

        return candidates.length ? candidates[0].element : null;
    }


    async function waitForTransportScreenAfterDispatch(timeoutMs) {
        const started = Date.now();
        const limit = Number.isFinite(timeoutMs) ? timeoutMs : 5000;

        while (Date.now() - started < limit) {
            if (isTransportScreenBlockingQueueRestart()) {
                return true;
            }

            await wait(250);
        }

        return false;
    }

    async function handleTransportRequestsAfterDispatch(reason) {
        if (!isTransportAutomationAllowed()) return 'none';

        const firstFound = await waitForTransportScreenAfterDispatch(5000);

        if (!firstFound) {
            return 'none';
        }

        updateStatusBox('Transport request detected. Sending transport...');

        if (mfDebugEnabled) {
            debugLog('AUTO TRANSPORT', `${reason}: transport request detected.`);
        }

        let sentCount = 0;
        const started = Date.now();

        while (autoModeRunning && Date.now() - started < 90000 && sentCount < 25) {
            if (!isTransportScreenBlockingQueueRestart()) {
                break;
            }

            const sendButton = findTransportSendButton();

            if (!sendButton) {
                if (mfDebugEnabled) {
                    debugLog('AUTO TRANSPORT', `${reason}: transport screen found but no send/approach button found.`);
                }

                updateStatusBox('Transport request detected, but no transport send button was found.');
                return sentCount > 0 ? 'partial' : 'stuck';
            }

            const clicked = await clickExactApproachTransportButton(`auto-transport-${reason}`);

            if (!clicked) {
                const bruteClicked = await mfBruteClickFirstApproach(`auto-transport-police-brute-${reason}`);

                if (!bruteClicked) {
                    if (mfDebugEnabled) {
                        debugLog('AUTO TRANSPORT', `${reason}: Approach found but click helper did not click yet; waiting for Vue/iframe update.`);
                    }

                    await wait(1800);
                    continue;
                }
            }

            sentCount += 1;

            updateStatusBox(`Transport sent (${sentCount}). Checking for more transport requests...`);
        }

        if (sentCount > 0) {
            await wait(1200);

            const rehookWaitStarted = Date.now();

            while (
                isPostTransportRehookPending() &&
                !isManualAutoStopActive() &&
                Date.now() - rehookWaitStarted < 60000
            ) {
                await wait(500);
            }
        }

        if (mfDebugEnabled) {
            debugLog('AUTO TRANSPORT', `${reason}: completed. sent=${sentCount}`);
        }

        return sentCount > 0 ? 'sent' : 'none';
    }


    async function waitForQueueRestartAndOpenMission(reason) {
        // This function is entered only after the final mission's Dispatch
        // click succeeded. MissionChief often leaves old red update alerts
        // visible for a short time after Dispatch. Those stale alerts must
        // not cancel the final close / unattended-count / reopen workflow.
        if (mfQueueRestartWaiting) return false;

        mfQueueRestartWaiting = true;

        try {
            sessionStorage.setItem(
                MF_QUEUE_WAIT_ACTIVE_FLAG,
                'true'
            );
            sessionStorage.removeItem(
                MF_QUEUE_OPENING_MISSION_FLAG
            );
            sessionStorage.removeItem(
                MF_FINAL_QUEUE_DISPATCH_FLAG
            );
            sessionStorage.setItem('mf_auto_mode_running', 'true');
            autoModeRunning = true;

            updateStatusBox(`End of queue reached (${reason}). Closing mission and handing over to silent queue watcher...`);

            if (mfDebugEnabled) {
                debugLog('SILENT QUEUE', `handover started. reason=${reason}`);
            }

            startSilentQueueWatcher();

            const closed = await closeMissionScreenForQueueRestart();

            if (mfDebugEnabled) {
                debugLog('SILENT QUEUE', `Close clicked=${closed ? 'yes' : 'no'} | missionVisible=${isMissionScreenVisibleForQueueRestart() ? 'yes' : 'no'}`);
            }

            await wait(1000);

            updateStatusBox(
                `Silent queue watcher active. Waiting for ${getConfiguredQueueRestartThreshold()} unattended missions.`
            );
            return false;
        } finally {
            // Do not clear queue-wait here. The silent watcher owns the next open.
            mfQueueRestartWaiting = false;
        }
    }


    function readAutoAdvanceAfterDispatchState() {
        let state = null;

        try {
            state = JSON.parse(
                sessionStorage.getItem(
                    MF_AUTO_ADVANCE_AFTER_DISPATCH_KEY
                ) ||
                localStorage.getItem(
                    MF_AUTO_ADVANCE_AFTER_DISPATCH_KEY
                ) ||
                'null'
            );
        } catch (error) {
            state = null;
        }

        if (
            !state ||
            typeof state !== 'object'
        ) {
            return null;
        }

        const age =
            Date.now() -
            Number(
                state.clickedAt ||
                state.createdAt ||
                0
            );

        if (
            !Number.isFinite(age) ||
            age < 0 ||
            age > MF_AUTO_ADVANCE_MAX_AGE_MS
        ) {
            clearAutoAdvanceAfterDispatchState(
                'stale advance state'
            );

            return null;
        }

        return state;
    }

    function writeAutoAdvanceAfterDispatchState(
        state
    ) {
        if (
            !state ||
            typeof state !== 'object'
        ) {
            return false;
        }

        const encoded =
            JSON.stringify(state);

        try {
            sessionStorage.setItem(
                MF_AUTO_ADVANCE_AFTER_DISPATCH_KEY,
                encoded
            );
        } catch (error) {}

        // Fallback for MissionChief replacing the mission iframe/document.
        try {
            localStorage.setItem(
                MF_AUTO_ADVANCE_AFTER_DISPATCH_KEY,
                encoded
            );
        } catch (error) {}

        return true;
    }

    function clearAutoAdvanceAfterDispatchState(
        reason = ''
    ) {
        try {
            sessionStorage.removeItem(
                MF_AUTO_ADVANCE_AFTER_DISPATCH_KEY
            );
        } catch (error) {}

        try {
            localStorage.removeItem(
                MF_AUTO_ADVANCE_AFTER_DISPATCH_KEY
            );
        } catch (error) {}

        if (
            reason &&
            mfDebugEnabled
        ) {
            debugLog(
                'AUTO ADVANCE STATE',
                `Cleared | ${reason}`
            );
        }
    }

    function createAutoAdvanceAfterDispatchState(
        reason,
        mode = 'auto'
    ) {
        const queueState =
            getNextMissionQueueState();

        const nextButton =
            document.querySelector(
                'a#mission_next_mission_btn'
            );

        const nextHref =
            (
                nextButton?.getAttribute(
                    'href'
                ) ||
                queueState?.href ||
                ''
            ).trim();

        // Next Mission (0) has no real destination.
        if (
            !queueState?.exists ||
            queueState.count === 0 ||
            !nextHref ||
            nextHref === '#'
        ) {
            return null;
        }

        return {
            createdAt:
                Date.now(),
            clickedAt:
                Date.now(),
            missionId:
                getCurrentMissionIdForQueueRestart(),
            missionName:
                getCurrentMissionName(),
            reason:
                reason ||
                'dispatch',
            mode:
                mode === 'manual'
                    ? 'manual'
                    : 'auto',
            nextHref,
            nextTitle:
                queueState.title ||
                nextButton?.getAttribute(
                    'title'
                ) ||
                '',
            nextCount:
                queueState.count
        };
    }

    async function clickExactNextMissionAfterDispatch(
        state
    ) {
        const startedAt =
            Date.now();

        let nextButton = null;

        while (
            Date.now() - startedAt <
            8000
        ) {
            nextButton =
                document.querySelector(
                    'a#mission_next_mission_btn'
                );

            const href = (
                nextButton?.getAttribute(
                    'href'
                ) ||
                ''
            ).trim();

            if (
                nextButton &&
                href &&
                href !== '#'
            ) {
                break;
            }

            await wait(150);
        }

        const savedHref =
            String(
                state?.nextHref ||
                ''
            ).trim();

        const targetHref = (
            nextButton?.getAttribute(
                'href'
            ) ||
            savedHref
        ).trim();

        if (
            !targetHref ||
            targetHref === '#'
        ) {
            if (
                state?.mode === 'auto'
            ) {
                stopAutoMode(
                    'Auto stopped: the exact Next Mission link was not found after Dispatch.'
                );
            } else {
                updateStatusBox(
                    'Dispatch completed, but the exact Next Mission link was not found.'
                );
            }

            clearAutoAdvanceAfterDispatchState(
                'Next Mission link unavailable'
            );

            return false;
        }

        const mode =
            state?.mode === 'manual'
                ? 'manual'
                : 'auto';

        updateStatusBox(
            mode === 'auto'
                ? 'Auto Mode: clicking the exact Next Mission link...'
                : 'Dispatch completed. Opening the next mission...'
        );

        // Clear before navigation because the click replaces this document.
        clearAutoAdvanceAfterDispatchState(
            'clicking exact Next Mission link'
        );

        const missionIdBefore =
            getCurrentMissionIdForQueueRestart();

        clearAutoSelectionMissionGuard(
            'opening exact Next Mission'
        );

        resetVehicleLoadState();

        if (nextButton) {
            try {
                nextButton.scrollIntoView({
                    block: 'center',
                    inline: 'center'
                });
            } catch (error) {}

            try {
                nextButton.click();
            } catch (error) {
                realClickForQueueRestart(
                    nextButton
                );
            }

            // Give MissionChief's native handler a chance to navigate.
            await wait(450);
        }

        const missionIdAfter =
            getCurrentMissionIdForQueueRestart();

        if (
            missionIdBefore &&
            missionIdAfter &&
            missionIdAfter !==
                missionIdBefore
        ) {
            return true;
        }

        // Native click fallback: follow the exact link destination.
        try {
            const absoluteHref =
                new URL(
                    targetHref,
                    window.location.origin
                ).href;

            window.location.assign(
                absoluteHref
            );

            return true;
        } catch (error) {
            if (mode === 'auto') {
                stopAutoMode(
                    'Auto stopped: Next Mission navigation failed.'
                );
            } else {
                updateStatusBox(
                    'Dispatch completed, but Next Mission navigation failed.'
                );
            }

            return false;
        }
    }


    async function resumeAutoAdvanceAfterDispatch(
        source = 'unknown'
    ) {
        if (mfAutoAdvanceResumeActive) {
            return false;
        }

        const state =
            readAutoAdvanceAfterDispatchState();

        if (!state) {
            return false;
        }

        const mode =
            state.mode === 'manual'
                ? 'manual'
                : 'auto';

        if (
            mode === 'auto' &&
            (
                !autoModeRunning ||
                isManualAutoStopActive()
            )
        ) {
            clearAutoAdvanceAfterDispatchState(
                'Auto Mode no longer running'
            );

            return false;
        }

        mfAutoAdvanceResumeActive = true;

        try {
            const elapsed =
                Date.now() -
                Number(
                    state.clickedAt ||
                    Date.now()
                );

            if (elapsed < 800) {
                await wait(
                    800 - elapsed
                );
            }

            const currentMissionId =
                getCurrentMissionIdForQueueRestart();

            // Dispatch-and-next or another MissionChief navigation may
            // already have moved to a different mission.
            if (
                state.missionId &&
                currentMissionId &&
                currentMissionId !==
                    state.missionId
            ) {
                clearAutoAdvanceAfterDispatchState(
                    'MissionChief already opened the next mission'
                );

                if (mode === 'auto') {
                    clearAutoSelectionMissionGuard(
                        'next mission opened'
                    );

                    resetVehicleLoadState();

                    requireMissionUpdateFirstPass(
                        'mission changed during dispatch continuation'
                    );

                    setTimeout(
                        function() {
                            if (
                                autoModeRunning &&
                                !isManualAutoStopActive() &&
                                !autoModeLoopActive
                            ) {
                                runAutoModeLoop();
                            }
                        },
                        300
                    );
                } else {
                    updateStatusBox(
                        'Next mission opened.'
                    );
                }

                return true;
            }

            updateStatusBox(
                mode === 'auto'
                    ? 'Auto Mode: dispatch refresh complete. Moving to the next mission...'
                    : 'Dispatch refresh complete. Moving to the next mission...'
            );

            // Only enter the transport workflow when a transport screen is
            // already present. Ordinary missions go straight to the exact
            // Next Mission link without waiting five seconds.
            if (
                mode === 'auto' &&
                isTransportScreenBlockingQueueRestart()
            ) {
                const transportResult =
                    await handleTransportRequestsAfterDispatch(
                        `advance-resume-${source}`
                    );

                if (
                    transportResult === 'stuck'
                ) {
                    clearAutoAdvanceAfterDispatchState(
                        'transport request stuck'
                    );

                    stopAutoMode(
                        'Auto stopped: transport request found but no send button was found.'
                    );

                    return false;
                }

                if (
                    transportResult === 'sent' ||
                    transportResult === 'partial'
                ) {
                    clearAutoAdvanceAfterDispatchState(
                        'transport rehook owns continuation'
                    );

                    return true;
                }
            }

            return await clickExactNextMissionAfterDispatch(
                state
            );
        } finally {
            mfAutoAdvanceResumeActive = false;
        }
    }


    function readAutoPostDispatchUpgradeState() {
        // Retired in V10.6.54. Clear any pending state left by an older
        // version and never resume the post-dispatch upgrade workflow.
        clearAutoPostDispatchUpgradeState(
            'post-dispatch upgrade workflow retired'
        );
        return null;
    }


    function writeAutoPostDispatchUpgradeState(
        state
    ) {
        const encoded =
            JSON.stringify(state);

        try {
            sessionStorage.setItem(
                MF_AUTO_UPGRADE_PENDING_KEY,
                encoded
            );
        } catch (error) {}

        // LocalStorage is a fallback when MissionChief replaces the
        // mission frame instead of reloading the current document.
        try {
            localStorage.setItem(
                MF_AUTO_UPGRADE_PENDING_KEY,
                encoded
            );
        } catch (error) {}
    }

    function clearAutoPostDispatchUpgradeState(
        reason = ''
    ) {
        try {
            sessionStorage.removeItem(
                MF_AUTO_UPGRADE_PENDING_KEY
            );
        } catch (error) {}

        try {
            localStorage.removeItem(
                MF_AUTO_UPGRADE_PENDING_KEY
            );
        } catch (error) {}

        if (
            reason &&
            mfDebugEnabled
        ) {
            debugLog(
                'AUTO UPGRADE STATE',
                `Cleared | ${reason}`
            );
        }
    }

    function getMissionUpdateRowsSignature(
        rows
    ) {
        const canonicalRows =
            new Map();

        (
            Array.isArray(rows)
                ? rows
                : []
        ).forEach(row => {
            if (
                row
                    ?.isTrainedPersonnelRequirement
            ) {
                const signature =
                    getTrainedPersonnelRequirementsSignature(
                        row
                            .personnelTrainingRequirements
                    );

                if (signature) {
                    canonicalRows.set(
                        `trained-personnel:${signature}`,
                        getTrainedPersonnelVehicleTarget(
                            row
                                .personnelTrainingRequirements
                        )
                    );
                }

                return;
            }

            const amount =
                Math.max(
                    0,
                    parseInt(
                        row?.stillNeeded,
                        10
                    ) || 0
                );

            if (amount <= 0) {
                return;
            }

            const mappedName =
                resolveUnitName(
                    row?.unitName
                );

            const canonicalName =
                normaliseVehicleText(
                    mappedName ||
                    row?.unitName
                );

            if (!canonicalName) {
                return;
            }

            canonicalRows.set(
                canonicalName,
                Math.max(
                    canonicalRows.get(
                        canonicalName
                    ) || 0,
                    amount
                )
            );
        });

        return Array.from(
            canonicalRows.entries()
        )
            .map(
                ([name, amount]) =>
                    `${name}:${amount}`
            )
            .sort()
            .join('|');
    }

    function getVisibleExactNormalDispatchButton(
        requireSelectedVehicles = false
    ) {
        return Array.from(
            document.querySelectorAll(
                '#mission_alarm_btn'
            )
        ).find(button => {
            if (
                !isVisibleForQueueRestart(button)
            ) {
                return false;
            }

            const disabled =
                button.hasAttribute('disabled') ||
                button.getAttribute(
                    'aria-disabled'
                ) === 'true' ||
                button.classList.contains(
                    'disabled'
                );

            if (disabled) return false;

            const title = (
                button.getAttribute('title') ||
                ''
            )
                .replace(/\s+/g, ' ')
                .trim()
                .toLowerCase();

            const buttonText = (
                button.textContent ||
                button.innerText ||
                ''
            )
                .replace(/\s+/g, ' ')
                .trim()
                .toLowerCase();

            const badge =
                button.querySelector(
                    '#vehicle_amount'
                ) ||
                document.getElementById(
                    'vehicle_amount'
                );

            const selectedAmount =
                parseInt(
                    (
                        badge?.textContent ||
                        badge?.innerText ||
                        '0'
                    ).replace(/[^0-9]/g, ''),
                    10
                ) ||
                0;

            const checkedVehicleCount =
                document.querySelectorAll(
                    'input.vehicle_checkbox:checked'
                ).length;

            const selectionRequirementMet =
                !requireSelectedVehicles ||
                selectedAmount >= 1 ||
                checkedVehicleCount >= 1;

            return (
                title.startsWith('dispatch') &&
                !title.includes('next') &&
                buttonText.startsWith(
                    'dispatch'
                ) &&
                selectionRequirementMet
            );
        }) || null;
    }

    async function waitForExactNormalDispatchButton(
        timeoutMs = 4000,
        requireSelectedVehicles = false
    ) {
        const startedAt = Date.now();

        while (
            Date.now() - startedAt <
            timeoutMs
        ) {
            const button =
                getVisibleExactNormalDispatchButton(
                    requireSelectedVehicles
                );

            if (button) return button;

            await wait(100);
        }

        return null;
    }

    function hasVisibleVehicleDispatchSuccessAlert() {
        return Array.from(
            document.querySelectorAll(
                '.alert.alert-success, [id^="alert_success_"]'
            )
        ).some(alert => {
            if (
                !isElementVisible(alert)
            ) {
                return false;
            }

            const text = (
                alert.textContent ||
                alert.innerText ||
                ''
            )
                .replace(/\s+/g, ' ')
                .trim();

            return /has successfully been dispatched\.?/i.test(
                text
            );
        });
    }

    async function clickAutoMissionDispatchForUpgradeCheck(
        missionCredits,
        isUpgradePass = false
    ) {
        const credits =
            Number(missionCredits || 0);

        // Preserve the existing high-value share behaviour on the initial
        // dispatch. Upgrade re-dispatches use the normal Dispatch button.
        if (
            !isUpgradePass &&
            credits > MF_SHARE_CREDIT_THRESHOLD
        ) {
            if (clickDispatchAndShareOnly()) {
                return {
                    clicked: true,
                    shared: true
                };
            }
        }

        const dispatchButton =
            await waitForExactNormalDispatchButton(
                isUpgradePass
                    ? 8000
                    : 4000,
                true
            );

        if (!dispatchButton) {
            return {
                clicked: false,
                shared: false
            };
        }

        try {
            dispatchButton.scrollIntoView({
                block: 'center',
                inline: 'center'
            });
        } catch (error) {}

        try {
            dispatchButton.click();

            return {
                clicked: true,
                shared: false
            };
        } catch (error) {
            return {
                clicked: false,
                shared: false
            };
        }
    }

    async function waitForAutoPostDispatchUpgradeRows(
        state
    ) {
        const elapsed =
            Date.now() -
            Number(
                state.clickedAt ||
                Date.now()
            );

        // MissionChief performs a small page refresh after Dispatch.
        if (elapsed < 1000) {
            await wait(
                1000 - elapsed
            );
        }

        const startedAt =
            Date.now();

        const beforeRowsSignature =
            String(
                state.beforeRowsSignature ||
                ''
            );

        // When there were no update rows before Dispatch, any new stable
        // row can be treated as an upgrade immediately. When there were
        // existing rows, they must first disappear or change.
        let staleBaselineReleased =
            !beforeRowsSignature;

        let lastSignature = '';
        let stableSince = 0;
        let latestRows = [];

        while (
            Date.now() - startedAt <
            MF_AUTO_UPGRADE_WAIT_MS
        ) {
            if (
                !autoModeRunning ||
                isManualAutoStopActive()
            ) {
                return {
                    stopped: true,
                    movedMission: false,
                    rows: []
                };
            }

            const currentMissionId =
                getCurrentMissionIdForQueueRestart();

            if (
                state.missionId &&
                currentMissionId &&
                currentMissionId !==
                    state.missionId
            ) {
                return {
                    stopped: false,
                    movedMission: true,
                    rows: []
                };
            }

            latestRows =
                readMissionUpdateRows({
                    silent: true
                });

            const signature =
                getMissionUpdateRowsSignature(
                    latestRows
                );

            if (!staleBaselineReleased) {
                if (!signature) {
                    // The old update rows have cleared. A later row is a
                    // genuine post-dispatch upgrade.
                    staleBaselineReleased =
                        true;

                    lastSignature = '';
                    stableSince =
                        Date.now();

                    await wait(200);
                    continue;
                }

                if (
                    signature ===
                    beforeRowsSignature
                ) {
                    // Still seeing the exact rows that existed before
                    // Dispatch. Ignore them rather than selecting twice.
                    lastSignature =
                        signature;

                    stableSince =
                        Date.now();

                    await wait(200);
                    continue;
                }

                // A different requirement appeared without an empty gap.
                // Treat this changed signature as a genuine upgrade.
                staleBaselineReleased =
                    true;

                lastSignature =
                    signature;

                stableSince =
                    Date.now();

                await wait(200);
                continue;
            }

            if (
                signature !==
                lastSignature
            ) {
                lastSignature =
                    signature;

                stableSince =
                    Date.now();
            }

            if (
                latestRows.length > 0 &&
                Date.now() - stableSince >=
                    500
            ) {
                return {
                    stopped: false,
                    movedMission: false,
                    rows: latestRows
                };
            }

            await wait(200);
        }

        return {
            stopped: false,
            movedMission: false,
            rows: []
        };
    }

    async function clickNextMissionAfterAutoUpgrade() {
        // The post-dispatch upgrade watch completed with no further
        // requirements. Give MissionChief time to expose Next Mission.
        await wait(800);

        const startedAt = Date.now();
        let nextButton = null;

        while (
            Date.now() - startedAt < 5000
        ) {
            nextButton =
                document.querySelector(
                    '#mission_next_mission_btn'
                );

            if (
                nextButton &&
                isVisibleForQueueRestart(
                    nextButton
                )
            ) {
                break;
            }

            await wait(200);
        }

        if (!nextButton) {
            stopAutoMode(
                'Auto stopped: Next Mission button was not found after Dispatch.'
            );
            return false;
        }

        updateStatusBox(
            'Auto Mode: Dispatch accepted. Opening next mission...'
        );

        try {
            nextButton.click();
        } catch (error) {
            const clicked =
                realClickForQueueRestart(
                    nextButton
                );

            if (!clicked) {
                stopAutoMode(
                    'Auto stopped: Next Mission could not be opened.'
                );
                return false;
            }
        }

        // If MissionChief changes the document, the new script instance
        // will restore Auto Mode. This fallback covers same-document loads.
        setTimeout(
            function() {
                if (
                    autoModeRunning &&
                    !isManualAutoStopActive() &&
                    isMissionPage() &&
                    !autoModeLoopActive
                ) {
                    requireMissionUpdateFirstPass(
                        'next mission after Dispatch'
                    );
                    runAutoModeLoop();
                }
            },
            700
        );

        return true;
    }

    async function resumeAutoPostDispatchUpgrade(
        source = 'retired'
    ) {
        // Retired in V10.6.54. This compatibility stub ensures an old or
        // delayed callback cannot restart the removed upgrade-wait workflow.
        clearAutoPostDispatchUpgradeState(
            `retired callback ignored: ${source}`
        );
        mfAutoUpgradeResumeActive = false;
        return false;
    }


    async function handleAfterFinalQueueDispatch() {
        // Give MissionChief a brief moment to accept Dispatch, but do not
        // re-read old red alerts here. All requirement checks happened
        // before Dispatch and the click has already succeeded.
        await wait(800);

        if (!autoModeRunning) return false;

        // If the transport screen appears, do not close the modal.
        // The independent Approach watcher sends it every 4 seconds, then auto-close continuation handles the next mission.
        if (mfIsApproachTransportVisible() || isTransportScreenBlockingQueueRestart()) {
            updateStatusBox('Final mission transport detected. Sending Approach sequence...');
            markTransportSequenceActive();

            const started = Date.now();

            while (autoModeRunning && Date.now() - started < 90000) {
                if (mfIsApproachTransportVisible()) {
                    await mfBruteClickFirstApproach('after-final-dispatch');
                    await wait(300);
                    continue;
                }

                if (!hasVisibleApproachButtonForTransportRehook()) {
                    return false;
                }

                await wait(1000);
            }

            return false;
        }

        return await waitForQueueRestartAndOpenMission('after-final-dispatch');
    }


    function getCurrentAutoDispatchSelectionState() {
        const badge =
            document.getElementById(
                'vehicle_amount'
            );

        const badgeCount =
            parseInt(
                (
                    badge?.textContent ||
                    badge?.innerText ||
                    '0'
                ).replace(/[^0-9]/g, ''),
                10
            ) || 0;

        const checkedCount =
            document.querySelectorAll(
                'input.vehicle_checkbox:checked'
            ).length;

        return {
            badgeCount,
            checkedCount,
            selectedCount:
                Math.max(
                    badgeCount,
                    checkedCount
                )
        };
    }

    async function retryAutoSelectionWhenZero() {
        const before =
            getCurrentAutoDispatchSelectionState();

        if (
            before.selectedCount > 0
        ) {
            return true;
        }

        updateStatusBox(
            'Auto Mode selected 0 vehicles. Waiting for the vehicle list and retrying once...'
        );

        await waitForVehicleCheckboxListStable(
            6000,
            900,
            {
                minimumWaitMs: 700,
                requireNonZero: true
            }
        );

        resetVehicleLoadState();
        changeDispatchBoxColor(false);

        const updateRows =
            readMissionUpdateRows({
                silent: true
            });

        if (updateRows.length > 0) {
            clearSelectionGuards();

            await preparePoliceVehicleSafetyForRows(
                updateRows,
                'AUTO ZERO-SELECTION UPDATE'
            );

            handleMissionUpdateUnits(
                false,
                updateRows
            );
        } else {
            try {
                await withTimeout(
                    handleCombinedLogic(),
                    45000,
                    'Auto Mode zero-selection retry'
                );
            } catch (error) {
                console.warn(
                    'Mission Finder zero-selection retry failed:',
                    error
                );
            }

            // Catch an update that appeared while the normal requirements
            // were being retried.
            const lateUpdateRows =
                readMissionUpdateRows({
                    silent: true
                });

            if (
                lateUpdateRows.length > 0
            ) {
                clearSelectionGuards();

                await preparePoliceVehicleSafetyForRows(
                    lateUpdateRows,
                    'AUTO LATE UPDATE'
                );

                handleMissionUpdateUnits(
                    false,
                    lateUpdateRows
                );
            }
        }

        await waitForFastDispatchReadiness(
            'zero-selection recovery',
            {
                minimumWait: 200,
                stableFor: 350,
                timeout: 1600
            }
        );

        const after =
            getCurrentAutoDispatchSelectionState();

        if (
            after.selectedCount > 0
        ) {
            updateStatusBox(
                `Auto Mode retry selected ${after.selectedCount} vehicle(s).`
            );

            return true;
        }

        vehicleLoadState.ready = false;
        changeDispatchBoxColor(false);

        updateStatusBox(
            'Auto Mode retry still selected 0 vehicles.'
        );

        return false;
    }


    async function runAutoModeLoop() {
        if (isManualAutoStopActive()) return;
        if (autoModeLoopActive) return;

        if (!isCurrentMissionExecutionOwner('Auto Mode start')) {
            removeMissionFinderPanelForClosedMission(
                'inactive previous mission instance'
            );
            return;
        }

        autoModeLoopActive = true;

        while (autoModeRunning && !isManualAutoStopActive()) {
            if (!isCurrentMissionExecutionOwner('Auto Mode cycle')) {
                removeMissionFinderPanelForClosedMission(
                    'another mission became active'
                );
                break;
            }

            if (sessionStorage.getItem(MF_QUEUE_OPENING_MISSION_FLAG) === 'true') {
                if (getMainMissionOpenLockRemaining() <= 0) {
                    sessionStorage.removeItem(MF_QUEUE_OPENING_MISSION_FLAG);
                    mfSilentQueueOpening = false;
                    releaseMainMissionOpenLock('opening flag expired');

                    if (mfDebugEnabled) {
                        debugLog('QUEUE OPEN GUARD', 'Expired queue-opening flag cleared.');
                    }
                } else {
                    updateStatusBox('Queue restart is opening the next mission...');
                    await wait(350);
                    continue;
                }
            }

            if (sessionStorage.getItem(MF_FINAL_QUEUE_DISPATCH_FLAG) === 'true') {
                const restarted = await waitForQueueRestartAndOpenMission('same-screen-after-final-dispatch');

                if (restarted) {
                    continue;
                }

                break;
            }

            if (!isMissionPage()) {
                updateStatusBox('Auto Mode waiting for next mission...');
                await wait(500);
                continue;
            }

            const autoCycleMissionId =
                getCurrentMissionIdForQueueRestart();

            clearAutoSelectionMissionGuard(
                'starting Auto mission cycle'
            );

            resetVehicleLoadState();

            changeDispatchBoxColor(
                false
            );

            resetStaffingBlockForCurrentMission(
                'Auto Mode cycle'
            );

            const earlyUpdateRows =
                await waitForMissionUpdateBeforeUnitFinder(
                    'auto-cycle-before-vehicle-load'
                );

            if (
                !autoModeRunning ||
                isManualAutoStopActive()
            ) {
                break;
            }

            let prefetchedAttachmentRowsPromise = null;

            if (
                detectAndLatchStaffingBlock(
                    'after-update-first-gate'
                )
            ) {
                vehicleLoadState.ready = false;
                changeDispatchBoxColor(false);
            } else {
                // Start the mission-help request while MissionChief finishes
                // stabilising the vehicle rows. This keeps the exact same data
                // source but removes a serial network wait from Auto Mode.
                prefetchedAttachmentRowsPromise =
                    readLiveMissionRequirements();

                const autoVehicleLoadState =
                    await ensureVehicleListLoaded({
                        stableTimeoutMs:
                            MF_AUTO_VEHICLE_LIST_STABLE_TIMEOUT_MS,
                        stableForMs:
                            MF_AUTO_VEHICLE_LIST_STABLE_FOR_MS,
                        minimumSettleMs:
                            MF_AUTO_VEHICLE_LIST_MIN_SETTLE_MS,
                        loadTimeoutMs:
                            MF_AUTO_VEHICLE_LIST_LOAD_TIMEOUT_MS,
                        requireNonZero: true
                    });

                if (!autoVehicleLoadState.ready) {
                    vehicleLoadState.ready = false;
                    changeDispatchBoxColor(false);

                    stopAutoMode(
                        'Auto stopped: the complete vehicle list did not become stable before Unit Finder. No units were selected.'
                    );

                    break;
                }
            }

            // V10.6.50 source parity: Auto Mode now follows the same
            // sequence as pressing the manual buttons:
            //   1. Unit Finder reads the mission-help attachment table named
            //      "Vehicle and Personnel Requirements".
            //   2. Mission Update then reads the visible Live Mission
            //      Requirements/patient update source.
            //
            // The previous update-first branch could see a patient alert,
            // skip Unit Finder completely, and therefore send only Ambulances
            // while ignoring attachment requirements such as Police Cars x5.
            let autoMissionUpdateRowsHandled = 0;

            if (
                earlyUpdateRows.length > 0 &&
                mfDebugEnabled
            ) {
                debugLog(
                    'AUTO SOURCE PARITY',
                    `Early Mission Update snapshot detected (${earlyUpdateRows.length} row(s)); Unit Finder attachment will still run first, then the update snapshot will be re-read.`
                );
            }

            if (mfStaffingBlockActive) {
                updateStatusBox(
                    'Auto Mode: staffing/qualification shortage found. Skipping extra vehicle selection.'
                );
                changeDispatchBoxColor(false);
            } else {
                updateStatusBox(
                    'Auto Mode running Unit Finder from Vehicle and Personnel Requirements...'
                );

                try {
                    await withTimeout(
                        handleCombinedLogic({
                            vehicleListAlreadyLoaded: true,
                            attachmentRowsPromise: prefetchedAttachmentRowsPromise
                        }),
                        45000,
                        'Auto Mode Unit Finder'
                    );
                } catch (error) {
                    console.warn(
                        'Mission Finder Auto Mode timeout:',
                        error
                    );
                    debugLog(
                        'AUTO TIMEOUT',
                        error.message ||
                        String(error)
                    );
                    changeDispatchBoxColor(false);
                }

                await waitForFastDispatchReadiness(
                    'Unit Finder selection',
                    {
                        minimumWait: 150,
                        stableFor: 300,
                        timeout: 1200
                    }
                );

                if (!autoModeRunning) break;

                updateStatusBox(
                    'Auto Mode checking the manual Mission Update source...'
                );

                // Use one fixed snapshot, exactly as the manual Mission Update
                // button does when clicked.
                const postUnitFinderUpdateRows =
                    readMissionUpdateRows();

                autoMissionUpdateRowsHandled =
                    postUnitFinderUpdateRows.length;

                clearSelectionGuards();

                await preparePoliceVehicleSafetyForRows(
                    postUnitFinderUpdateRows,
                    'AUTO MISSION UPDATE'
                );

                const updated =
                    handleMissionUpdateUnits(
                        false,
                        postUnitFinderUpdateRows
                    );

                if (updated) {
                    await waitForFastDispatchReadiness(
                        'mission update fix',
                        {
                            minimumWait: 100,
                            stableFor: 250,
                            timeout: 900
                        }
                    );
                }
            }

            if (!autoModeRunning) break;

            if (!isCurrentMissionExecutionOwner('before Auto dispatch validation')) {
                removeMissionFinderPanelForClosedMission(
                    'stale Auto Mode instance blocked before dispatch'
                );
                break;
            }

            const missionIdAfterSelection =
                getCurrentMissionIdForQueueRestart();

            if (
                !autoCycleMissionId ||
                !missionIdAfterSelection ||
                missionIdAfterSelection !==
                    autoCycleMissionId
            ) {
                clearAutoSelectionMissionGuard(
                    'mission changed during Unit Finder'
                );

                resetVehicleLoadState();

                updateStatusBox(
                    'Auto Mode: mission changed during selection. Restarting Unit Finder on the current mission...'
                );

                await wait(300);
                continue;
            }

            markAutoSelectionCompletedForCurrentMission(
                autoMissionUpdateRowsHandled > 0
                    ? 'Unit Finder and Mission Update completed'
                    : 'Unit Finder completed'
            );

            if (
                !mfStaffingBlockActive &&
                getCurrentAutoDispatchSelectionState()
                    .selectedCount === 0
            ) {
                await retryAutoSelectionWhenZero();
            }

            if (!autoModeRunning) break;

            const visibleProblemAlert = getVisibleInlineProblemAlertText();

            if (visibleProblemAlert) {
                vehicleLoadState.ready = false;
                changeDispatchBoxColor(false);

                if (mfDebugEnabled) {
                    debugLog('READY BLOCK', `Visible problem alert before dispatch: ${visibleProblemAlert.slice(0, 260)}`);
                }
            }

            const personnelQualificationAlert =
                getInlinePersonnelQualificationAlertText();

            detectAndLatchStaffingBlock(
                'final dispatch decision'
            );

            if (
                personnelQualificationAlert ||
                mfStaffingBlockActive
            ) {
                vehicleLoadState.ready = false;
                changeDispatchBoxColor(false);

                if (mfDebugEnabled) {
                    debugLog('PERSONNEL ALERT', `Inline alert found before dispatch decision: ${personnelQualificationAlert.slice(0, 240)}`);
                }
            }

            if (
                !isAutoSelectionValidForCurrentMission()
            ) {
                clearAutoSelectionMissionGuard(
                    'selection belongs to another mission'
                );

                resetVehicleLoadState();

                updateStatusBox(
                    'Auto Mode: blocked a stale Dispatch. Running Unit Finder on the current mission...'
                );

                await wait(250);
                continue;
            }

            if (!vehicleLoadState.ready) {
                const staffingBlocked =
                    !!personnelQualificationAlert ||
                    mfStaffingBlockActive;

                updateStatusBox(
                    staffingBlocked
                        ? 'Auto Mode: staffing/qualification shortage. No more vehicles selected; dispatching to skip mission...'
                        : 'Auto Mode: units not ready. Dispatching to skip mission...'
                );

                addMissionLogEntry(
                    'skipped',
                    getCurrentMissionName(),
                    staffingBlocked
                        ? 'Staffing/qualification shortage'
                        : 'Units not ready',
                    null
                );

                if (
                    !staffingBlocked &&
                    getCurrentAutoDispatchSelectionState()
                        .selectedCount === 0
                ) {
                    stopAutoMode(
                        'Auto stopped: Unit Finder selected 0 vehicles after a full-list retry. The mission was not dispatched.'
                    );
                    break;
                }

                const queueStateBeforeDispatch = getNextMissionQueueState();
                const finalQueueMission = isFinalQueueSignal(queueStateBeforeDispatch);
                logQueueState('skip-before-dispatch', queueStateBeforeDispatch, finalQueueMission);

                clearAutoAdvanceAfterDispatchState(
                    'Auto skip uses native Dispatch-and-next'
                );

                if (finalQueueMission) {
                    sessionStorage.setItem(
                        MF_FINAL_QUEUE_DISPATCH_FLAG,
                        'true'
                    );
                }

                if (!isCurrentMissionExecutionOwner('before skip dispatch')) {
                    removeMissionFinderPanelForClosedMission(
                        'stale Auto Mode skip dispatch blocked'
                    );
                    break;
                }

                if (!clickDispatchOnly()) {
                    sessionStorage.removeItem(
                        MF_FINAL_QUEUE_DISPATCH_FLAG
                    );

                    stopAutoMode(
                        finalQueueMission
                            ? 'Auto stopped. Final mission Dispatch button was not found.'
                            : 'Auto stopped. Dispatch & Next button was not found while skipping.'
                    );

                    break;
                }

                clearAutoSelectionMissionGuard(
                    'skip mission dispatched'
                );

                resetVehicleLoadState();

                if (finalQueueMission) {
                    const restarted =
                        await handleAfterFinalQueueDispatch();

                    if (restarted) {
                        continue;
                    }

                    break;
                }

                updateStatusBox(
                    'Auto Mode: Dispatch & Next clicked. Waiting for the next mission...'
                );

                break;
            }

            updateStatusBox('Auto Mode dispatching mission...');
            const missionName = getCurrentMissionName();
            const missionCredits = getMissionCredits();

            const queueStateBeforeDispatch = getNextMissionQueueState();
            const finalQueueMission = isFinalQueueSignal(queueStateBeforeDispatch);
            logQueueState('complete-before-dispatch', queueStateBeforeDispatch, finalQueueMission);

            clearAutoAdvanceAfterDispatchState(
                'Auto completed mission dispatch'
            );

            if (finalQueueMission) {
                sessionStorage.setItem(
                    MF_FINAL_QUEUE_DISPATCH_FLAG,
                    'true'
                );
            }

            if (!isCurrentMissionExecutionOwner('before completed dispatch')) {
                removeMissionFinderPanelForClosedMission(
                    'stale Auto Mode completed dispatch blocked'
                );
                break;
            }

            const dispatchResult =
                clickMissionDispatchByValue(
                    missionCredits,
                    'Auto Mode completed mission'
                );

            if (!dispatchResult.clicked) {
                sessionStorage.removeItem(
                    MF_FINAL_QUEUE_DISPATCH_FLAG
                );

                stopAutoMode(
                    finalQueueMission
                        ? 'Auto stopped: final mission Dispatch button was not found.'
                        : 'Auto stopped: Dispatch & Next button was not found.'
                );

                break;
            }

            clearAutoSelectionMissionGuard(
                'completed mission dispatched'
            );

            addMissionLogEntry(
                'completed',
                missionName,
                dispatchResult.shared
                    ? 'Dispatched and shared'
                    : '',
                missionCredits
            );

            resetVehicleLoadState();

            updateStatusBox(
                dispatchResult.shared
                    ? 'Auto Mode: Dispatch & Share clicked. Waiting for the next mission...'
                    : finalQueueMission
                        ? 'Auto Mode: final mission dispatched. Restarting the queue...'
                        : 'Auto Mode: Dispatch & Next clicked. Waiting for the next mission...'
            );

            if (finalQueueMission) {
                const restarted =
                    await handleAfterFinalQueueDispatch();

                if (restarted) {
                    continue;
                }

                break;
            }

            break;
        }

        autoModeLoopActive = false;
        updateAutoModeButton();
    }

    function initialize() {
        if (!isMissionPage()) return;

        if (!claimCurrentMissionExecutionOwnership('initialize')) {
            document.getElementById('mission-finder-wrapper')?.remove();
            return;
        }

        synchroniseMissionInstanceState('initialize');
        cleanupDuplicatePanels();

        if (document.getElementById('mission-finder-wrapper')) {
            if (readAllyStealPendingState()) {
                setTimeout(
                    function() {
                        resumeAllyStealAfterDispatchRefresh(
                            'existing initialized panel'
                        );
                    },
                    150
                );
            } else if (
                readAutoAdvanceAfterDispatchState()
            ) {
                setTimeout(
                    function() {
                        resumeAutoAdvanceAfterDispatch(
                            'existing initialized panel'
                        );
                    },
                    150
                );
            }

            return;
        }

        createControlPanel();

        if (readAllyStealPendingState()) {
            updateStatusBox(
                'Ally Steal: dispatch refresh detected. Resuming confirmation...'
            );

            setTimeout(
                function() {
                    resumeAllyStealAfterDispatchRefresh(
                        'mission initialize after reload'
                    );
                },
                150
            );

            return;
        }

        if (
            readAutoAdvanceAfterDispatchState()
        ) {
            updateStatusBox(
                'Dispatch & Share transition detected. Confirming the next mission...'
            );

            setTimeout(
                function() {
                    resumeAutoAdvanceAfterDispatch(
                        'mission initialize after reload'
                    );
                },
                150
            );

            return;
        }

        if (autoModeRunning) {
            requireMissionUpdateFirstPass(
                'mission panel initialized'
            );

            if (mfDebugEnabled) {
                debugLog(
                    'UPDATE FIRST GATE',
                    'Deferred automatic full vehicle-list loading until the mission update precheck completes.'
                );
            }
        } else {
            clickVehicleDisplayBarImmediately();
        }
    }

    function getVehicleCheckboxListSignature() {
        const boxes = Array.from(
            document.querySelectorAll(
                'input.vehicle_checkbox'
            )
        );

        const ids = boxes.map(box => {
            return String(
                box.id ||
                box.value ||
                getMissionVehicleId(box) ||
                ''
            );
        });

        const vehicleRows =
            document.querySelectorAll(
                'tr.vehicle_select_table_tr, #vehicle_table tr[vehicle_id], #vehicle_table tr[data-vehicle-id]'
            ).length;

        return {
            boxes,
            signature:
                `${boxes.length}|${vehicleRows}|${ids.join(',')}`
        };
    }

    function getVisibleVehicleListLoadControl() {
        return Array.from(
            document.querySelectorAll(
                'a.btn-warning.missing_vehicles_load, a.missing_vehicles_load'
            )
        ).find(loadControl => {
            if (!loadControl || !loadControl.isConnected) {
                return false;
            }

            const disabled =
                loadControl.hasAttribute('disabled') ||
                loadControl.getAttribute('aria-disabled') === 'true' ||
                loadControl.classList.contains('disabled');

            if (disabled) return false;

            try {
                return isElementVisible(loadControl);
            } catch (_error) {
                try {
                    return getComputedStyle(loadControl).display !== 'none' &&
                        loadControl.getClientRects().length > 0;
                } catch (_innerError) {
                    return true;
                }
            }
        }) || null;
    }

    function getVehicleListLoadControlToken(loadControl) {
        if (!loadControl) return '';

        const href = String(
            loadControl.getAttribute('href') ||
            loadControl.href ||
            ''
        ).trim();

        const text = String(
            loadControl.textContent ||
            loadControl.innerText ||
            ''
        ).replace(/\s+/g, ' ').trim();

        return `${href}|${text}`;
    }

    function isVehicleListLoadControlVisible() {
        return !!getVisibleVehicleListLoadControl();
    }

    function isVehicleListLoadingIndicatorVisible() {
        return Array.from(
            document.querySelectorAll(
                '#vehicle_table .loading, #vehicle_table .spinner, ' +
                '.vehicle_select_table .loading, .vehicle_select_table .spinner, ' +
                '[data-vehicle-loading="true"]'
            )
        ).some(element => {
            try {
                return getComputedStyle(element).display !== 'none' &&
                    element.getClientRects().length > 0;
            } catch (_error) {
                return true;
            }
        });
    }

    async function waitForVehicleCheckboxListStable(
        timeoutMs = 6000,
        stableForMs = 800,
        options = {}
    ) {
        const startedAt =
            Date.now();

        const minimumWaitMs = Number.isFinite(
            options.minimumWaitMs
        )
            ? Math.max(0, options.minimumWaitMs)
            : 0;

        const requireNonZero =
            options.requireNonZero === true;

        let lastSignature = '';
        let stableSince =
            Date.now();

        while (
            Date.now() - startedAt <
            timeoutMs
        ) {
            const snapshot =
                getVehicleCheckboxListSignature();

            if (
                snapshot.signature !==
                lastSignature
            ) {
                lastSignature =
                    snapshot.signature;
                stableSince =
                    Date.now();
            }

            const elapsed =
                Date.now() - startedAt;

            const stableElapsed =
                Date.now() - stableSince;

            const loadControlVisible =
                isVehicleListLoadControlVisible();

            const loadingIndicatorVisible =
                isVehicleListLoadingIndicatorVisible();

            if (
                elapsed >= minimumWaitMs &&
                stableElapsed >= stableForMs &&
                !loadControlVisible &&
                !loadingIndicatorVisible &&
                (!requireNonZero || snapshot.boxes.length > 0)
            ) {
                return {
                    ready: true,
                    count: snapshot.boxes.length,
                    signature: snapshot.signature,
                    elapsed
                };
            }

            await wait(125);
        }

        const finalSnapshot =
            getVehicleCheckboxListSignature();

        return {
            ready: false,
            count: finalSnapshot.boxes.length,
            signature: finalSnapshot.signature,
            elapsed: Date.now() - startedAt,
            timedOut: true
        };
    }

    async function ensureVehicleListLoaded(options = {}) {
        const stableTimeoutMs = Number.isFinite(options.stableTimeoutMs)
            ? Math.max(1500, options.stableTimeoutMs)
            : 10000;

        const stableForMs = Number.isFinite(options.stableForMs)
            ? Math.max(400, options.stableForMs)
            : 1200;

        const loadTimeoutMs = Number.isFinite(options.loadTimeoutMs)
            ? Math.max(5000, options.loadTimeoutMs)
            : 60000;

        const pageProgressTimeoutMs = Number.isFinite(
            options.pageProgressTimeoutMs
        )
            ? Math.max(3000, options.pageProgressTimeoutMs)
            : 15000;

        const minimumSettleMs = Number.isFinite(options.minimumSettleMs)
            ? Math.max(0, options.minimumSettleMs)
            : 800;

        const requireNonZero = options.requireNonZero !== false;
        const missionKeyAtStart = getLocalMissionInstanceKey();
        const loadingStartedAt = Date.now();

        let loadClicked = false;
        let clickedPages = 0;
        let lastCompletedControlToken = '';
        let lastCompletedVehicleSignature = '';
        let loadFailureReason = '';

        while (Date.now() - loadingStartedAt < loadTimeoutMs) {
            const currentMissionKey = getLocalMissionInstanceKey();

            if (
                missionKeyAtStart &&
                currentMissionKey &&
                currentMissionKey !== missionKeyAtStart
            ) {
                loadFailureReason =
                    'mission changed while loading vehicles';
                break;
            }

            const vehicleDisplayBar =
                getVisibleVehicleListLoadControl();

            if (!vehicleDisplayBar) break;

            const beforeSnapshot =
                getVehicleCheckboxListSignature();

            const controlToken =
                getVehicleListLoadControlToken(vehicleDisplayBar);

            // Never fire the same AJAX page twice while MissionChief is still
            // replacing the control. A new href/text token or changed vehicle
            // signature must appear before another click is permitted.
            if (
                controlToken === lastCompletedControlToken &&
                beforeSnapshot.signature ===
                    lastCompletedVehicleSignature
            ) {
                await wait(150);
                continue;
            }

            updateStatusBox(
                `Vehicle display limited. Loading additional vehicle page ${clickedPages + 1}...`
            );

            if (mfDebugEnabled) {
                debugLog(
                    'VEHICLE PAGE LOAD',
                    `Click ${clickedPages + 1} | control=${controlToken || 'unknown'} | before=${beforeSnapshot.signature}`
                );
            }

            invalidateVehicleCheckboxCache();

            let clickIssued = false;

            try {
                vehicleDisplayBar.click();
                clickIssued = true;
            } catch (_error) {}

            if (!clickIssued) {
                clickIssued = realClickForQueueRestart(vehicleDisplayBar);
            }

            if (!clickIssued) {
                loadFailureReason =
                    'limited vehicle control could not be clicked';
                break;
            }

            loadClicked = true;
            clickedPages += 1;

            const pageStartedAt = Date.now();
            let rowProgressSeen = false;
            let controlTransitionSeen = false;
            let lastPageSignature = beforeSnapshot.signature;
            let signatureStableSince = Date.now();
            let pageCompleted = false;

            while (
                Date.now() - pageStartedAt <
                pageProgressTimeoutMs
            ) {
                const pageMissionKey =
                    getLocalMissionInstanceKey();

                if (
                    missionKeyAtStart &&
                    pageMissionKey &&
                    pageMissionKey !== missionKeyAtStart
                ) {
                    loadFailureReason =
                        'mission changed while an additional vehicle page was loading';
                    break;
                }

                invalidateVehicleCheckboxCache();

                const currentSnapshot =
                    getVehicleCheckboxListSignature();

                const currentControl =
                    getVisibleVehicleListLoadControl();

                const currentControlToken =
                    getVehicleListLoadControlToken(currentControl);

                if (
                    currentSnapshot.signature !==
                    lastPageSignature
                ) {
                    lastPageSignature = currentSnapshot.signature;
                    signatureStableSince = Date.now();
                }

                rowProgressSeen =
                    rowProgressSeen ||
                    currentSnapshot.signature !==
                        beforeSnapshot.signature;

                controlTransitionSeen =
                    controlTransitionSeen ||
                    !vehicleDisplayBar.isConnected ||
                    !currentControl ||
                    currentControl !== vehicleDisplayBar ||
                    currentControlToken !== controlToken;

                const pageElapsed = Date.now() - pageStartedAt;
                const signatureStableFor =
                    Date.now() - signatureStableSince;

                const loadingIndicatorVisible =
                    isVehicleListLoadingIndicatorVisible();

                if (
                    rowProgressSeen &&
                    controlTransitionSeen &&
                    pageElapsed >= 800 &&
                    signatureStableFor >= 700 &&
                    !loadingIndicatorVisible
                ) {
                    pageCompleted = true;
                    break;
                }

                await wait(150);
            }

            if (loadFailureReason) break;

            if (!pageCompleted) {
                loadFailureReason =
                    `additional vehicle page ${clickedPages} made no confirmed progress`;
                break;
            }

            invalidateVehicleCheckboxCache();

            const completedSnapshot =
                getVehicleCheckboxListSignature();

            lastCompletedControlToken = controlToken;
            lastCompletedVehicleSignature =
                completedSnapshot.signature;

            if (mfDebugEnabled) {
                debugLog(
                    'VEHICLE PAGE LOAD',
                    `Completed page ${clickedPages} | after=${completedSnapshot.signature} | next=${getVehicleListLoadControlToken(getVisibleVehicleListLoadControl()) || 'none'}`
                );
            }

            // Allow MissionChief to install the next offset_page link or remove
            // the final limited-display control before the next loop pass.
            await wait(300);
        }

        const remainingLoadControl =
            getVisibleVehicleListLoadControl();

        if (!loadFailureReason && remainingLoadControl) {
            loadFailureReason =
                'additional vehicle page loading timed out';
        }

        if (loadFailureReason) {
            const failedSnapshot =
                getVehicleCheckboxListSignature();

            updateStatusBox(
                `Vehicle list did not finish loading safely: ${loadFailureReason}.`
            );

            if (mfDebugEnabled) {
                debugLog(
                    'VEHICLE PAGE LOAD',
                    `FAILED | ${loadFailureReason} | pages=${clickedPages} | ${failedSnapshot.signature}`
                );
            }

            return {
                ready: false,
                count: failedSnapshot.boxes.length,
                signature: failedSnapshot.signature,
                elapsed: Date.now() - loadingStartedAt,
                timedOut: true,
                loadClicked,
                clickedPages,
                reason: loadFailureReason
            };
        }

        // The final Load More control can disappear before the last row batch
        // is inserted. Require the full ID signature and table row count to
        // remain unchanged after every offset_page control has gone.
        const stability =
            await waitForVehicleCheckboxListStable(
                stableTimeoutMs,
                stableForMs,
                {
                    minimumWaitMs:
                        loadClicked
                            ? minimumSettleMs
                            : Math.min(minimumSettleMs, 350),
                    requireNonZero
                }
            );

        invalidateVehicleCheckboxCache();

        if (!stability.ready) {
            updateStatusBox(
                `Vehicle list did not finish loading safely (${stability.count} vehicle rows).`
            );

            return {
                ...stability,
                loadClicked,
                clickedPages
            };
        }

        updateStatusBox(
            clickedPages > 0
                ? `All additional vehicle pages loaded and stable (${stability.count} vehicles across ${clickedPages} load${clickedPages === 1 ? '' : 's'}).`
                : `Vehicle list loaded and stable (${stability.count} vehicles).`
        );

        if (mfDebugEnabled) {
            debugLog(
                'VEHICLE PAGE LOAD',
                `READY | pages=${clickedPages} | vehicles=${stability.count} | elapsed=${Date.now() - loadingStartedAt}ms`
            );
        }

        return {
            ...stability,
            loadClicked,
            clickedPages
        };
    }

    async function clickVehicleDisplayBarImmediately() {
        await ensureVehicleListLoaded();
    }

    function shouldRunBackgroundAutomationWatchers() {
        return !!(
            autoModeRunning ||
            sessionStorage.getItem('mf_auto_mode_running') === 'true' ||
            localStorage.getItem('mf_auto_mode_running') === 'true' ||
            sessionStorage.getItem(MF_QUEUE_WAIT_ACTIVE_FLAG) === 'true' ||
            sessionStorage.getItem(MF_FINAL_QUEUE_DISPATCH_FLAG) === 'true' ||
            isPostTransportRehookPending() ||
            isRecentTransportRehookWindowActive()
        );
    }

    const MF_MUTATION_VEHICLE_SELECTOR =
        'input.vehicle_checkbox, #vehicle_table, .vehicle_select_table_tr, ' +
        'a.missing_vehicles_load, .missing_vehicles_load';

    const MF_MUTATION_MISSION_SELECTOR =
        '#mission_general_info, #mission_help, #mission_content, ' +
        '#iframe-inside-container, .mission_content, ' +
        '#mc-map-command-toolkit-mission-requirements, ' +
        '[data-mcms-requirements-panel="1"], ' +
        'table[aria-label="Live mission requirements"], ' +
        '.alert-danger, [role="alert"], .mission_update, ' +
        '.mission_update_info, #mission_alarm_btn, #alarm_button, ' +
        '.vm--modal, .modal, .lightbox, iframe';

    const MF_MUTATION_PATIENT_SELECTOR =
        '.mission_patient, [id^="patient_"], [data-patient-id], .badge';

    const MF_MUTATION_PANEL_SELECTOR =
        '#mission-finder-wrapper, #control-panel, ' +
        '#vehicle-load-list-box';

    const MF_MUTATION_TRANSPORT_SELECTOR =
        '.vehicle-window, .redesign-wrapper[type="vehicle"], ' +
        '.vm--modal button.btn-success, .modal button.btn-success, ' +
        '.lightbox button.btn-success, iframe';

    const MF_MUTATION_MISSION_TARGET_SELECTOR =
        '#mission_general_info, #mission_help, #mission_content, ' +
        '#iframe-inside-container, .mission_content, ' +
        '#mc-map-command-toolkit-mission-requirements, ' +
        '[data-mcms-requirements-panel="1"], ' +
        'table[aria-label="Live mission requirements"], ' +
        '.alert-danger, [role="alert"], .mission_update, ' +
        '.mission_update_info, #mission_alarm_btn, #alarm_button';

    const MF_MUTATION_RELEVANT_SELECTOR =
        `${MF_MUTATION_VEHICLE_SELECTOR}, ` +
        `${MF_MUTATION_MISSION_SELECTOR}, ` +
        `${MF_MUTATION_PATIENT_SELECTOR}, ` +
        `${MF_MUTATION_PANEL_SELECTOR}, ` +
        `${MF_MUTATION_TRANSPORT_SELECTOR}`;

    const MF_MUTATION_RELEVANT_TARGET_SELECTOR =
        `${MF_MUTATION_VEHICLE_SELECTOR}, ` +
        `${MF_MUTATION_MISSION_TARGET_SELECTOR}, ` +
        `${MF_MUTATION_PATIENT_SELECTOR}, ` +
        `${MF_MUTATION_TRANSPORT_SELECTOR}`;

    function resetMainMutationFlags() {
        mfMainMutationFlags = {
            relevant: false,
            vehicleListChanged: false,
            missionContextChanged: false,
            patientChanged: false,
            panelChanged: false,
            transportChanged: false
        };
    }

    function mutationNodeMatches(node, selector) {
        if (!node || node.nodeType !== 1) return false;

        try {
            return (
                node.matches?.(selector) ||
                !!node.querySelector?.(selector)
            );
        } catch (_error) {
            return false;
        }
    }

    function mutationTargetWithin(target, selector) {
        if (!target || target.nodeType !== 1) return false;

        try {
            return !!target.closest?.(selector);
        } catch (_error) {
            return false;
        }
    }

    function classifyMissionFinderMutations(records) {
        const flags = {
            relevant: false,
            vehicleListChanged: false,
            missionContextChanged: false,
            patientChanged: false,
            panelChanged: false,
            transportChanged: false
        };

        const inspectNode = node => {
            if (!node || node.nodeType !== 1) return;

            if (!mutationNodeMatches(node, MF_MUTATION_RELEVANT_SELECTOR)) {
                return;
            }

            if (mutationNodeMatches(node, MF_MUTATION_VEHICLE_SELECTOR)) {
                flags.vehicleListChanged = true;
                flags.relevant = true;
            }

            if (mutationNodeMatches(node, MF_MUTATION_MISSION_SELECTOR)) {
                flags.missionContextChanged = true;
                flags.relevant = true;
            }

            if (mutationNodeMatches(node, MF_MUTATION_PATIENT_SELECTOR)) {
                flags.patientChanged = true;
                flags.relevant = true;
            }

            if (mutationNodeMatches(node, MF_MUTATION_PANEL_SELECTOR)) {
                flags.panelChanged = true;
                flags.relevant = true;
            }

            if (mutationNodeMatches(node, MF_MUTATION_TRANSPORT_SELECTOR)) {
                flags.transportChanged = true;
                flags.relevant = true;
            }
        };

        for (const record of records || []) {
            const target = record.target;
            const targetRelevant = mutationTargetWithin(
                target,
                MF_MUTATION_RELEVANT_TARGET_SELECTOR
            );

            if (targetRelevant && mutationTargetWithin(target, MF_MUTATION_VEHICLE_SELECTOR)) {
                flags.vehicleListChanged = true;
                flags.relevant = true;
            }

            if (targetRelevant && mutationTargetWithin(target, MF_MUTATION_MISSION_TARGET_SELECTOR)) {
                flags.missionContextChanged = true;
                flags.relevant = true;
            }

            if (targetRelevant && mutationTargetWithin(target, MF_MUTATION_PATIENT_SELECTOR)) {
                flags.patientChanged = true;
                flags.relevant = true;
            }

            if (targetRelevant && mutationTargetWithin(target, MF_MUTATION_TRANSPORT_SELECTOR)) {
                flags.transportChanged = true;
                flags.relevant = true;
            }

            record.addedNodes?.forEach(inspectNode);
            record.removedNodes?.forEach(inspectNode);

            if (
                flags.vehicleListChanged &&
                flags.missionContextChanged &&
                flags.patientChanged &&
                flags.panelChanged &&
                flags.transportChanged
            ) {
                break;
            }
        }

        // Ignore mutations produced by Mission Finder's own panel. Mission
        // content, live requirement, patient and transport roots are all
        // covered by the selectors above, so a broad fallback is unnecessary.

        return flags;
    }

    function mergeMainMutationFlags(flags) {
        if (!flags) return;

        Object.keys(mfMainMutationFlags).forEach(key => {
            mfMainMutationFlags[key] =
                mfMainMutationFlags[key] ||
                !!flags[key];
        });
    }

    function removeMissionFinderPanelForClosedMission(reason = '') {
        const wrapper = document.getElementById('mission-finder-wrapper');

        if (wrapper) {
            wrapper.remove();
        }

        stopSessionRuntimeTicker();

        if (mfDebugRenderFrame !== null) {
            try {
                cancelAnimationFrame(mfDebugRenderFrame);
            } catch (_error) {}
            clearTimeout(mfDebugRenderFrame);
            mfDebugRenderFrame = null;
        }

        if (mfVehicleLoadRenderFrame !== null) {
            try {
                cancelAnimationFrame(mfVehicleLoadRenderFrame);
            } catch (_error) {}
            clearTimeout(mfVehicleLoadRenderFrame);
            mfVehicleLoadRenderFrame = null;
        }

        invalidateVehicleCheckboxCache();
        invalidateMissionContextCaches();
        invalidatePatientCountCache();

        if (mfDebugEnabled && reason) {
            debugLog('PANEL LIFECYCLE', `Removed after mission closed | ${reason}`);
        }
    }

    function stopBackgroundWatcherIntervalsOnly() {
        if (mfSilentQueueWatcherTimer) {
            clearInterval(mfSilentQueueWatcherTimer);
            mfSilentQueueWatcherTimer = null;
        }

        if (mfGlobalTransportWatcherTimer) {
            clearInterval(mfGlobalTransportWatcherTimer);
            mfGlobalTransportWatcherTimer = null;
        }

        if (mfBruteApproachWatcherTimer) {
            clearInterval(mfBruteApproachWatcherTimer);
            mfBruteApproachWatcherTimer = null;
        }

        if (mfPostTransportRehookTimer) {
            clearInterval(mfPostTransportRehookTimer);
            mfPostTransportRehookTimer = null;
        }
    }

    function syncBackgroundAutomationWatchers() {
        if (!MF_IS_TOP_WINDOW) return;

        autoModeRunning =
            !isManualAutoStopActive() &&
            (
                sessionStorage.getItem('mf_auto_mode_running') === 'true' ||
                localStorage.getItem('mf_auto_mode_running') === 'true'
            );

        mfQueueRestartEnabled =
            localStorage.getItem(
                'mf_next_queue_restart_enabled_v10'
            ) !== 'false';

        if (shouldRunBackgroundAutomationWatchers()) {
            startSilentQueueWatcher();
            startBruteApproachTransportWatcher();
            startPostTransportRehookWatcher();
        } else {
            stopBackgroundWatcherIntervalsOnly();
        }
    }

    function installBackgroundWatcherSupervisor() {
        if (!MF_IS_TOP_WINDOW) return;

        if (!mfBackgroundStorageHandler) {
            mfBackgroundStorageHandler = function(event) {
                const key = String(event?.key || '');

                if (
                    !key ||
                    key.startsWith('mf_')
                ) {
                    syncBackgroundAutomationWatchers();
                }
            };

            window.addEventListener(
                'storage',
                mfBackgroundStorageHandler
            );
        }

        if (!mfBackgroundWatcherSupervisorTimer) {
            // One low-frequency supervisor replaces three always-on heavy
            // DOM-scanning intervals while Auto Mode is off. The storage
            // listener normally reacts immediately; this is the safety net.
            mfBackgroundWatcherSupervisorTimer = setInterval(
                syncBackgroundAutomationWatchers,
                5000
            );
        }

        syncBackgroundAutomationWatchers();
    }

    function scheduleAutoModeLoopResume(reason = 'mutation observer') {
        if (mfAutoLoopResumeTimer) return;

        mfAutoLoopResumeTimer = setTimeout(() => {
            mfAutoLoopResumeTimer = null;

            if (
                autoModeRunning &&
                isMissionPage() &&
                !autoModeLoopActive &&
                !mfAutoAdvanceResumeActive &&
                !mfAutoUpgradeResumeActive &&
                !readAutoPostDispatchUpgradeState() &&
                !readAutoAdvanceAfterDispatchState() &&
                !isManualAutoStopActive()
            ) {
                if (mfDebugEnabled) {
                    debugLog(
                        'AUTO RESUME COALESCED',
                        reason
                    );
                }

                runAutoModeLoop();
            }
        }, 200);
    }

    function flushMissionFinderMutationWork() {
        mfMainMutationFlushTimer = null;

        const flags = { ...mfMainMutationFlags };
        resetMainMutationFlags();

        if (flags.vehicleListChanged) {
            invalidateVehicleCheckboxCache();
            mfDispatchReadinessExpensiveCache.expiresAt = 0;
        }

        if (flags.missionContextChanged) {
            invalidateMissionContextCaches();
        }

        if (flags.patientChanged) {
            invalidatePatientCountCache();
            mfDispatchReadinessExpensiveCache.expiresAt = 0;
        }

        if (flags.transportChanged) {
            invalidateTransportCaches();
        }

        const missionPage = isMissionPage();
        const wrapper = document.getElementById('mission-finder-wrapper');

        if (
            missionPage &&
            wrapper &&
            !isCurrentMissionExecutionOwner('mutation ownership check')
        ) {
            removeMissionFinderPanelForClosedMission(
                'previous mission instance lost ownership'
            );
        } else if (missionPage && !wrapper) {
            initialize();
        } else if (!missionPage && wrapper) {
            removeMissionFinderPanelForClosedMission(
                'coalesced mission DOM change'
            );
        }

        if (flags.panelChanged) {
            const wrappers = document.querySelectorAll(
                '#mission-finder-wrapper'
            );

            const controlPanel = document.getElementById(
                'control-panel'
            );

            if (
                wrappers.length > 1 ||
                (
                    controlPanel &&
                    !controlPanel.closest('#mission-finder-wrapper')
                )
            ) {
                cleanupDuplicatePanels();
            }
        }

        if (autoModeRunning && missionPage && flags.relevant) {
            scheduleAutoModeLoopResume(
                'filtered/coalesced DOM mutation'
            );
        }
    }

    function scheduleMissionFinderMutationWork(records = []) {
        const flags = classifyMissionFinderMutations(records);

        if (!flags.relevant) return;

        mergeMainMutationFlags(flags);

        if (mfMainMutationFlushTimer) return;

        mfMainMutationFlushTimer = setTimeout(
            flushMissionFinderMutationWork,
            200
        );
    }

    function cleanupMissionFinderRuntime() {
        if (mfMainMutationObserver) {
            mfMainMutationObserver.disconnect();
            mfMainMutationObserver = null;
        }

        if (mfIssueRecorderObserver) {
            mfIssueRecorderObserver.disconnect();
            mfIssueRecorderObserver = null;
        }

        if (mfMainMutationFlushTimer) {
            clearTimeout(mfMainMutationFlushTimer);
            mfMainMutationFlushTimer = null;
        }

        if (mfAutoLoopResumeTimer) {
            clearTimeout(mfAutoLoopResumeTimer);
            mfAutoLoopResumeTimer = null;
        }

        if (mfIssueRecorderMutationTimer) {
            clearTimeout(mfIssueRecorderMutationTimer);
            mfIssueRecorderMutationTimer = null;
        }

        if (mfDebugRenderFrame !== null) {
            try {
                cancelAnimationFrame(mfDebugRenderFrame);
            } catch (_error) {}
            clearTimeout(mfDebugRenderFrame);
            mfDebugRenderFrame = null;
        }

        if (mfVehicleLoadRenderFrame !== null) {
            try {
                cancelAnimationFrame(mfVehicleLoadRenderFrame);
            } catch (_error) {}
            clearTimeout(mfVehicleLoadRenderFrame);
            mfVehicleLoadRenderFrame = null;
        }

        stopSessionRuntimeTicker();

        mfMissingUnitRetryIntervals.forEach(intervalId => {
            clearInterval(intervalId);
        });
        mfMissingUnitRetryIntervals.clear();

        stopBackgroundWatcherIntervalsOnly();

        if (mfBackgroundWatcherSupervisorTimer) {
            clearInterval(mfBackgroundWatcherSupervisorTimer);
            mfBackgroundWatcherSupervisorTimer = null;
        }

        if (mfBackgroundStorageHandler) {
            window.removeEventListener(
                'storage',
                mfBackgroundStorageHandler
            );
            mfBackgroundStorageHandler = null;
        }

        if (mfMissionFinderResizeHandler) {
            window.removeEventListener(
                'resize',
                mfMissionFinderResizeHandler
            );
            window.removeEventListener(
                'orientationchange',
                mfMissionFinderResizeHandler
            );
            window.removeEventListener(
                'pageshow',
                mfMissionFinderResizeHandler
            );
            window.visualViewport?.removeEventListener(
                'resize',
                mfMissionFinderResizeHandler
            );
            window.visualViewport?.removeEventListener(
                'scroll',
                mfMissionFinderResizeHandler
            );
            mfMissionFinderResizeHandler = null;
        }

        invalidateVehicleCheckboxCache();
        invalidateMissionContextCaches();
        invalidatePatientCountCache();
        invalidateTransportCaches();
        mfVehicleMatchCandidateCache.clear();
        resetMainMutationFlags();
    }

    function installMissionFinderRuntimeCleanup() {
        if (mfRuntimeCleanupInstalled) return;
        mfRuntimeCleanupInstalled = true;

        window.addEventListener(
            'pagehide',
            cleanupMissionFinderRuntime,
            { once: true }
        );
    }

    function startMissionFinderObserver() {
        if (mfMainMutationObserver) return;

        installIssueRecorderWatchers();
        installMissionFinderRuntimeCleanup();

        if (MF_IS_TOP_WINDOW) {
            installManualMissionClickFlagClearer();
            installBackgroundWatcherSupervisor();

            if (
                localStorage.getItem(
                    'mf_post_transport_rehook_pending_v1'
                ) === 'true' ||
                isRecentTransportRehookWindowActive()
            ) {
                forceAutoModeBackOnForTransportRehook();

                setTimeout(() => {
                    openFirstMissionAfterTransportAutoClose(
                        'startup-pending-rehook'
                    );
                }, 2500);
            }
        }

        if (isMissionPage()) initialize();

        mfMainMutationObserver = new MutationObserver(records => {
            scheduleMissionFinderMutationWork(records);
        });

        mfMainMutationObserver.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    if (document.body) {
        startMissionFinderObserver();
    } else {
        document.addEventListener(
            'DOMContentLoaded',
            startMissionFinderObserver,
            { once: true }
        );
    }

})();
    } catch (error) {
        console.error('[MissionChief Complete Tools] Mission Finder module startup failed:', error);
    }
})();