Files
HC_APTBS/Resources/Strings.en.xaml
LucianoDev 37d099cdbd feat: add Ford VP44 unlock progress dialog, K-Line fast unlock, localization, safety dialogs, and settings
Unlock progress UI:
- UnlockProgressDialog with dark-themed progress ring, phase indicator, elapsed
  time, and cancel/close buttons (non-modal, draggable borderless window)
- UnlockProgressViewModel with event-driven progress tracking via IUnlockService
- Triggers on pump selection (manual or K-Line auto-detect), not test start

UnlockService rewrite:
- Persistent CAN senders that outlive the unlock sequence (StopSenders on pump change)
- Concurrent K-Line fast unlock: awaits session Connected, sends RAM timer shortcut
  ({02 88 02 03 A8 01 00}), verifies via CAN TestUnlock before skipping wait
- Fix Type 1 verification (Value == 0 means unlocked, was inverted)

K-Line fast unlock support:
- IKwpService.TryFastUnlockAsync / KwpService implementation

Additional features:
- ILocalizationService with ES/EN resource dictionaries and runtime switching
- Safety dialogs: VoltageWarning, OilPumpConfirm, RpmSafetyWarning
- SettingsDialog for app configuration
- BenchService enhancements, ConfigurationService improvements, PDF report updates
- All UI strings localized via DynamicResource

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 13:22:48 +02:00

323 lines
22 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=System.Runtime">
<!-- ══════════════════════════════════════════════════════════════════
English (ENG)
══════════════════════════════════════════════════════════════════ -->
<!-- ── App ──────────────────────────────────────────────────────────── -->
<sys:String x:Key="App.Title">HC_APTBS — Herlic Test Bench</sys:String>
<sys:String x:Key="App.LanguageLabel">ESP</sys:String>
<!-- ── Menu ─────────────────────────────────────────────────────────── -->
<sys:String x:Key="Menu.Settings">Settings</sys:String>
<!-- ── Status bar / connection indicators ───────────────────────────── -->
<sys:String x:Key="Status.Label">Status:</sys:String>
<sys:String x:Key="Status.Can">CAN</sys:String>
<sys:String x:Key="Status.Bench">Bench</sys:String>
<sys:String x:Key="Status.Pump">Pump</sys:String>
<sys:String x:Key="Status.KLine">K-Line</sys:String>
<sys:String x:Key="Status.Connected">Connected</sys:String>
<sys:String x:Key="Status.ConnectionFailed">Connection failed</sys:String>
<sys:String x:Key="Status.Disconnected">Disconnected</sys:String>
<!-- ── Bench section ────────────────────────────────────────────────── -->
<sys:String x:Key="Bench.Header">Bench</sys:String>
<sys:String x:Key="Bench.ConnectCan">Connect CAN</sys:String>
<sys:String x:Key="Bench.DisconnectCan">Disconnect CAN</sys:String>
<sys:String x:Key="Bench.Rpm">rpm</sys:String>
<sys:String x:Key="Bench.Target">Target:</sys:String>
<sys:String x:Key="Bench.Voltage">V:</sys:String>
<sys:String x:Key="Bench.TempIn">T. In:</sys:String>
<sys:String x:Key="Bench.TempOut">T. Out:</sys:String>
<sys:String x:Key="Bench.Temp4">T. 4:</sys:String>
<sys:String x:Key="Bench.TempTank">T. Tank:</sys:String>
<sys:String x:Key="Bench.P1">P1:</sys:String>
<sys:String x:Key="Bench.P2">P2:</sys:String>
<sys:String x:Key="Bench.QDelivery">Q-Del.:</sys:String>
<sys:String x:Key="Bench.QOver">Q-Over:</sys:String>
<sys:String x:Key="Bench.CcStroke">cc/stroke</sys:String>
<sys:String x:Key="Bench.PumpRpm">P-RPM:</sys:String>
<sys:String x:Key="Bench.PumpTemp">P-Temp:</sys:String>
<sys:String x:Key="Bench.PumpMe">P-ME:</sys:String>
<sys:String x:Key="Bench.PumpFbkw">P-FBkW:</sys:String>
<sys:String x:Key="Bench.PsgEncoder">PSG Encoder:</sys:String>
<!-- ── Bench controls ───────────────────────────────────────────────── -->
<sys:String x:Key="Bench.Direction">Direction</sys:String>
<sys:String x:Key="Bench.Left">LEFT</sys:String>
<sys:String x:Key="Bench.Right">RIGHT</sys:String>
<sys:String x:Key="Bench.Motor">Bench Motor</sys:String>
<sys:String x:Key="Bench.Start">START</sys:String>
<sys:String x:Key="Bench.Stop">STOP</sys:String>
<sys:String x:Key="Bench.SetRpm">Set RPM:</sys:String>
<sys:String x:Key="Bench.Go">GO</sys:String>
<sys:String x:Key="Bench.OilPump">Oil Pump</sys:String>
<sys:String x:Key="Bench.OilOff">OIL OFF</sys:String>
<sys:String x:Key="Bench.OilOn">OIL ON</sys:String>
<sys:String x:Key="Bench.Counter">Counter</sys:String>
<sys:String x:Key="Bench.Turns">Turns:</sys:String>
<sys:String x:Key="Bench.Send">Send</sys:String>
<sys:String x:Key="Bench.Relays">Relays</sys:String>
<sys:String x:Key="Bench.Electronic">Electronic</sys:String>
<sys:String x:Key="Bench.DepositCooler">Deposit Cooler</sys:String>
<sys:String x:Key="Bench.DepositHeater">Deposit Heater</sys:String>
<!-- ── Pump live data ───────────────────────────────────────────────── -->
<sys:String x:Key="Pump.THyb">T-hyb</sys:String>
<sys:String x:Key="Pump.Rpm">RPM</sys:String>
<sys:String x:Key="Pump.TEin">T-ein</sys:String>
<sys:String x:Key="Pump.UnitRpm">1/min</sys:String>
<!-- ── Pump identification ──────────────────────────────────────────── -->
<sys:String x:Key="PumpId.Label">Pump:</sys:String>
<sys:String x:Key="PumpId.Dfi">DFI:</sys:String>
<sys:String x:Key="PumpId.PumpId">Pump ID:</sys:String>
<sys:String x:Key="PumpId.SerialNo">Serial No:</sys:String>
<sys:String x:Key="PumpId.ModelRef">Model Ref:</sys:String>
<sys:String x:Key="PumpId.DataRecord">Data Record:</sys:String>
<sys:String x:Key="PumpId.PumpCtrl">Pump Ctrl:</sys:String>
<sys:String x:Key="PumpId.ModelIndex">Model Index:</sys:String>
<sys:String x:Key="PumpId.SwVer1">SW Ver 1:</sys:String>
<sys:String x:Key="PumpId.SwVer2">SW Ver 2:</sys:String>
<sys:String x:Key="PumpId.Errors">Errors:</sys:String>
<sys:String x:Key="PumpId.Error">Error:</sys:String>
<sys:String x:Key="PumpId.ReadKLine">Read K-Line</sys:String>
<sys:String x:Key="PumpId.Disconnect">Disconnect</sys:String>
<sys:String x:Key="PumpId.NoKLineDevice">No K-Line device found</sys:String>
<!-- ── DFI management ───────────────────────────────────────────────── -->
<sys:String x:Key="Dfi.Read">READ</sys:String>
<sys:String x:Key="Dfi.Write">WRITE</sys:String>
<sys:String x:Key="Dfi.Label">DFI:</sys:String>
<sys:String x:Key="Dfi.Auto">AUTO</sys:String>
<!-- ── Pump control sliders ─────────────────────────────────────────── -->
<sys:String x:Key="PumpCtrl.Fbkw">FBKW - Advance Control</sys:String>
<sys:String x:Key="PumpCtrl.Me">ME - Quantity Control</sys:String>
<sys:String x:Key="PumpCtrl.PreInj">ME - Pre-inj Quantity</sys:String>
<sys:String x:Key="PumpCtrl.MinStepMax">Min / Step / Max</sys:String>
<sys:String x:Key="PumpCtrl.Min">Min</sys:String>
<sys:String x:Key="PumpCtrl.Step">Step</sys:String>
<sys:String x:Key="PumpCtrl.Max">Max</sys:String>
<!-- ── Bench parameter config ───────────────────────────────────────── -->
<sys:String x:Key="BenchParam.CanBusId">CAN-Bus ID (0x)</sys:String>
<sys:String x:Key="BenchParam.ByteL">Byte L</sys:String>
<sys:String x:Key="BenchParam.ByteH">Byte H</sys:String>
<sys:String x:Key="BenchParam.FilterAlpha">Filter α</sys:String>
<sys:String x:Key="BenchParam.EnableFormula">Enable formula</sys:String>
<!-- ── Angle display ────────────────────────────────────────────────── -->
<sys:String x:Key="Angle.Header">ADVANCE MONITORING</sys:String>
<sys:String x:Key="Angle.Psg">PSG:</sys:String>
<sys:String x:Key="Angle.Inj">INJ:</sys:String>
<sys:String x:Key="Angle.AbsDeg">ABS °:</sys:String>
<sys:String x:Key="Angle.LockDeg">LOCK °:</sys:String>
<sys:String x:Key="Angle.SetPsgZero">Set PSG zero reference</sys:String>
<sys:String x:Key="Angle.SetInjZero">Set INJ zero reference</sys:String>
<!-- ── Test panel ───────────────────────────────────────────────────── -->
<sys:String x:Key="Test.StartTest">▶ START TEST</sys:String>
<sys:String x:Key="Test.Stop">■ STOP</sys:String>
<sys:String x:Key="Test.Report">📄 Report</sys:String>
<sys:String x:Key="Test.ShowValues">Show values</sys:String>
<sys:String x:Key="Test.CheckAll">Check All</sys:String>
<sys:String x:Key="Test.SecondsRemaining">s remaining</sys:String>
<sys:String x:Key="Test.Condition">Cond:</sys:String>
<sys:String x:Key="Test.Measurement">Meas:</sys:String>
<sys:String x:Key="Test.MeasPerSec">M/s:</sys:String>
<sys:String x:Key="Test.Required">Required:</sys:String>
<sys:String x:Key="Test.TestLabel">Test:</sys:String>
<sys:String x:Key="Test.Critical">Critical</sys:String>
<sys:String x:Key="Test.Started">Test started...</sys:String>
<sys:String x:Key="Test.Stopped">Test stopped.</sys:String>
<!-- ── Test types ───────────────────────────────────────────────────── -->
<sys:String x:Key="TestType.Warmup">Warm-up</sys:String>
<sys:String x:Key="TestType.Adjustment">Adjustment</sys:String>
<sys:String x:Key="TestType.Flow">Flow</sys:String>
<sys:String x:Key="TestType.ServoValve">Servo valve</sys:String>
<sys:String x:Key="TestType.Upstroke">Upstroke</sys:String>
<sys:String x:Key="TestType.PreInjection">Pre-injection</sys:String>
<!-- ── Result display ───────────────────────────────────────────────── -->
<sys:String x:Key="Result.Phase">Phase</sys:String>
<sys:String x:Key="Result.Parameter">Parameter</sys:String>
<sys:String x:Key="Result.Target">Target</sys:String>
<sys:String x:Key="Result.Tolerance">Tol ±</sys:String>
<sys:String x:Key="Result.Average">Average</sys:String>
<sys:String x:Key="Result.ResultHeader">Result</sys:String>
<sys:String x:Key="Result.AllTests">All Tests</sys:String>
<!-- ── Common strings ───────────────────────────────────────────────── -->
<sys:String x:Key="Common.Pass">PASS</sys:String>
<sys:String x:Key="Common.Fail">FAIL</sys:String>
<sys:String x:Key="Common.Accept">Accept</sys:String>
<sys:String x:Key="Common.Cancel">Cancel</sys:String>
<sys:String x:Key="Common.Close">Close</sys:String>
<sys:String x:Key="Common.Save">Save</sys:String>
<sys:String x:Key="Common.Ok">OK</sys:String>
<sys:String x:Key="Common.Yes">Yes</sys:String>
<sys:String x:Key="Common.No">No</sys:String>
<sys:String x:Key="Common.Warning">WARNING</sys:String>
<sys:String x:Key="Common.Disabled">disabled</sys:String>
<!-- ── Dialog: Report ───────────────────────────────────────────────── -->
<sys:String x:Key="Dialog.Report.Title">Generate Report</sys:String>
<sys:String x:Key="Dialog.Report.ClientList">Client List</sys:String>
<sys:String x:Key="Dialog.Report.ClientData">Client Data</sys:String>
<sys:String x:Key="Dialog.Report.CompanyData">Company Data</sys:String>
<sys:String x:Key="Dialog.Report.Name">Name:</sys:String>
<sys:String x:Key="Dialog.Report.ClientInfo">Client information</sys:String>
<sys:String x:Key="Dialog.Report.Observations">Observations</sys:String>
<sys:String x:Key="Dialog.Report.Operator">Operator:</sys:String>
<sys:String x:Key="Dialog.Report.Company">Company:</sys:String>
<sys:String x:Key="Dialog.Report.CompanyInfo">Company information</sys:String>
<sys:String x:Key="Dialog.Report.DeleteClient">Delete Client</sys:String>
<sys:String x:Key="Dialog.Report.Generate">Generate</sys:String>
<!-- ── Dialog: User authentication ──────────────────────────────────── -->
<sys:String x:Key="Dialog.UserCheck.Title">User Authentication</sys:String>
<sys:String x:Key="Dialog.UserCheck.Username">Username:</sys:String>
<sys:String x:Key="Dialog.UserCheck.Password">Password:</sys:String>
<!-- ── Dialog: Voltage warning ──────────────────────────────────────── -->
<sys:String x:Key="Dialog.Voltage.Title">Power Supply Warning</sys:String>
<sys:String x:Key="Dialog.Voltage.VoltageLabel">VOLTAGE: </sys:String>
<sys:String x:Key="Dialog.Voltage.PumpRequires">The selected pump requires </sys:String>
<sys:String x:Key="Dialog.Voltage.PowerSupply"> power supply.</sys:String>
<sys:String x:Key="Dialog.Voltage.SwitchTo">SWITCH THE POWER SUPPLY TO </sys:String>
<!-- ── Dialog: Oil pump confirmation ────────────────────────────────── -->
<sys:String x:Key="Dialog.OilPump.Title">Oil Pump Activation</sys:String>
<sys:String x:Key="Dialog.OilPump.Message">You are about to activate the oil pump. Confirm that the oil level is adequate and all connections are secure before proceeding.</sys:String>
<sys:String x:Key="Dialog.OilPump.LeaksChecked">I have checked — no leaks, connections are ready</sys:String>
<!-- ── Dialog: RPM safety warning ───────────────────────────────────── -->
<sys:String x:Key="Dialog.RpmSafety.Title">RPM Safety Warning</sys:String>
<sys:String x:Key="Dialog.RpmSafety.Message">The oil pump is OFF. Running the bench motor without oil circulation can cause bearing damage to the pump.</sys:String>
<sys:String x:Key="Dialog.RpmSafety.OilAndProceed">Turn on oil pump and start the bench</sys:String>
<sys:String x:Key="Dialog.RpmSafety.ProceedWithout">I know what I'm doing — start without oil</sys:String>
<!-- ── Dialog: Unlock progress ──────────────────────────────────────── -->
<sys:String x:Key="Dialog.Unlock.Title">Immobilizer Unlock</sys:String>
<sys:String x:Key="Dialog.Unlock.Progress">PROGRESS</sys:String>
<sys:String x:Key="Dialog.Unlock.Phase1">Phase 1: Sending unlock signals</sys:String>
<sys:String x:Key="Dialog.Unlock.Phase2Testing">Phase 2: Testing</sys:String>
<sys:String x:Key="Dialog.Unlock.Phase2Sending">Phase 2: Sending...</sys:String>
<sys:String x:Key="Dialog.Unlock.Cancelled">CANCELLED</sys:String>
<sys:String x:Key="Dialog.Unlock.Unlocked">UNLOCKED</sys:String>
<sys:String x:Key="Dialog.Unlock.Failed">UNLOCK FAILED</sys:String>
<sys:String x:Key="Dialog.Unlock.TypeLabel">Type {0}</sys:String>
<!-- ── Dialog: K-Line errors ────────────────────────────────────────── -->
<sys:String x:Key="Dialog.KlineErrors.Title">K-Line Fault Codes</sys:String>
<sys:String x:Key="Dialog.KlineErrors.Header">Fault codes:</sys:String>
<sys:String x:Key="Dialog.KlineErrors.Read">Read</sys:String>
<sys:String x:Key="Dialog.KlineErrors.Clear">Clear</sys:String>
<!-- ── Dialog: Settings ───────────────────────────────────────────────── -->
<sys:String x:Key="Dialog.Settings.Title">Settings</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.General">General</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Safety">Safety</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Pid">PID</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Motor">Motor</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Company">Company</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.KLine">K-Line</sys:String>
<sys:String x:Key="Dialog.Settings.Tab.Advanced">Advanced</sys:String>
<sys:String x:Key="Dialog.Settings.Language">Language:</sys:String>
<sys:String x:Key="Dialog.Settings.DaysKeepLogs">Days to keep logs:</sys:String>
<sys:String x:Key="Dialog.Settings.TempMax">Max. temperature (°C):</sys:String>
<sys:String x:Key="Dialog.Settings.TempMin">Min. temperature (°C):</sys:String>
<sys:String x:Key="Dialog.Settings.SecurityRpmLimit">Safety RPM limit:</sys:String>
<sys:String x:Key="Dialog.Settings.MaxPressureBar">Max. pressure (bar):</sys:String>
<sys:String x:Key="Dialog.Settings.ToleranceUp">UP tolerance extension:</sys:String>
<sys:String x:Key="Dialog.Settings.TolerancePfp">PFP tolerance extension:</sys:String>
<sys:String x:Key="Dialog.Settings.IgnoreTin">Ignore T-in by default</sys:String>
<sys:String x:Key="Dialog.Settings.PidP">Proportional (P):</sys:String>
<sys:String x:Key="Dialog.Settings.PidI">Integral (I):</sys:String>
<sys:String x:Key="Dialog.Settings.PidD">Derivative (D):</sys:String>
<sys:String x:Key="Dialog.Settings.PidLoopMs">Loop period (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.EncoderRes">Encoder resolution:</sys:String>
<sys:String x:Key="Dialog.Settings.VoltMaxRpm">Voltage for max RPM (V):</sys:String>
<sys:String x:Key="Dialog.Settings.MaxRpm">Max RPM:</sys:String>
<sys:String x:Key="Dialog.Settings.RightRelay">Right = relay ON</sys:String>
<sys:String x:Key="Dialog.Settings.Relations">RPM-Voltage Table</sys:String>
<sys:String x:Key="Dialog.Settings.RelRpm">RPM</sys:String>
<sys:String x:Key="Dialog.Settings.RelVoltage">Voltage (V)</sys:String>
<sys:String x:Key="Dialog.Settings.AddRow">Add</sys:String>
<sys:String x:Key="Dialog.Settings.RemoveRow">Remove</sys:String>
<sys:String x:Key="Dialog.Settings.CompanyName">Company name:</sys:String>
<sys:String x:Key="Dialog.Settings.CompanyInfo">Company information:</sys:String>
<sys:String x:Key="Dialog.Settings.ReportLogo">Report logo path:</sys:String>
<sys:String x:Key="Dialog.Settings.BrowseLogoTitle">Select Logo Image</sys:String>
<sys:String x:Key="Dialog.Settings.KLinePort">K-Line port (FTDI):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshPorts">Refresh</sys:String>
<sys:String x:Key="Dialog.Settings.KLineHint">Select an FTDI device or type the serial number manually.</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshBench">Bench interface (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshReading">While reading K-Line (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshCanBus">CAN bus read (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshPumpReq">Pump request (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.RefreshPumpParams">Pump params (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.BlinkInterval">Blink interval (ms):</sys:String>
<sys:String x:Key="Dialog.Settings.FlasherInterval">Flasher interval (ms):</sys:String>
<!-- ── Error messages ───────────────────────────────────────────────── -->
<sys:String x:Key="Error.ReportGeneration">Failed to generate report:\n{0}</sys:String>
<sys:String x:Key="Error.ReportTitle">Report Error</sys:String>
<sys:String x:Key="Error.PsgSync">PSG sync pulse not detected. Check encoder connection.</sys:String>
<sys:String x:Key="Error.PsgTitle">PSG Error</sys:String>
<sys:String x:Key="Error.EmergencyStop">EMERGENCY STOP: {0}</sys:String>
<sys:String x:Key="Error.KLineNotFound">K-Line device not found. Check that the FTDI adapter is connected.</sys:String>
<sys:String x:Key="Error.KLineTitle">K-Line Error</sys:String>
<sys:String x:Key="Error.AuthInvalid">Invalid username or password.\n(Both are case-sensitive.)</sys:String>
<sys:String x:Key="Error.AuthTitle">Authentication Error</sys:String>
<!-- ── PDF Report ───────────────────────────────────────────────────── -->
<sys:String x:Key="Pdf.ReportTitle">VP44 INJECTION PUMP TEST REPORT</sys:String>
<sys:String x:Key="Pdf.GeneratedBy">Generated by HC-APTBS</sys:String>
<sys:String x:Key="Pdf.Page">Page </sys:String>
<sys:String x:Key="Pdf.Of"> of </sys:String>
<sys:String x:Key="Pdf.Date">Date: {0:dd/MM/yyyy HH:mm}</sys:String>
<sys:String x:Key="Pdf.Operator">Operator: {0}</sys:String>
<sys:String x:Key="Pdf.Client">Client: {0}</sys:String>
<sys:String x:Key="Pdf.PumpIdentification">PUMP IDENTIFICATION</sys:String>
<sys:String x:Key="Pdf.PumpId">Pump ID:</sys:String>
<sys:String x:Key="Pdf.Model">Model:</sys:String>
<sys:String x:Key="Pdf.SerialNo">Serial No.:</sys:String>
<sys:String x:Key="Pdf.Injector">Injector:</sys:String>
<sys:String x:Key="Pdf.Tube">Tube:</sys:String>
<sys:String x:Key="Pdf.Valve">Valve:</sys:String>
<sys:String x:Key="Pdf.Tension">Tension:</sys:String>
<sys:String x:Key="Pdf.Rotation">Rotation:</sys:String>
<sys:String x:Key="Pdf.LockAngle">Lock Angle:</sys:String>
<sys:String x:Key="Pdf.Measured">Measured:</sys:String>
<sys:String x:Key="Pdf.Chaveta">Chaveta:</sys:String>
<sys:String x:Key="Pdf.PreInj">Pre-Inj.:</sys:String>
<sys:String x:Key="Pdf.EcuData">ECU DATA (K-Line)</sys:String>
<sys:String x:Key="Pdf.OverallResult">OVERALL TEST RESULT</sys:String>
<sys:String x:Key="Pdf.TestsExecuted">Tests executed: {0} of {1}</sys:String>
<sys:String x:Key="Pdf.ParamsEvaluated">Parameters evaluated: {0} / {1} passed</sys:String>
<sys:String x:Key="Pdf.TestHeader">TEST: {0}</sys:String>
<sys:String x:Key="Pdf.Phase">Phase</sys:String>
<sys:String x:Key="Pdf.Parameter">Parameter</sys:String>
<sys:String x:Key="Pdf.Target">Target</sys:String>
<sys:String x:Key="Pdf.ToleranceHeader">Tolerance ±</sys:String>
<sys:String x:Key="Pdf.Average">Average</sys:String>
<sys:String x:Key="Pdf.Result">Result</sys:String>
<sys:String x:Key="Pdf.ErrorBits"> ⚠ Error bits: {0}</sys:String>
<sys:String x:Key="Pdf.NoSampleData">No sample data available for graphical display.</sys:String>
<sys:String x:Key="Pdf.ChartSamples">Samples: {0} | Target: {1} ± {2} | Average: {3} | Result: {4}</sys:String>
</ResourceDictionary>