{"$schema":"https://json.schemastore.org/sarif-2.1.0.json","version":"2.1.0","runs":[{"tool":{"driver":{"name":"codehealth","informationUri":"https://codehealth.canine.dev","rules":[{"id":"D1","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D1"},{"id":"D2","name":"Cognitive Complexity","shortDescription":{"text":"Cognitive Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/D2"},{"id":"D3","name":"God Classes","shortDescription":{"text":"God Classes"},"helpUri":"https://codehealth.canine.dev/dimensions/D3"},{"id":"D4","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/D4"},{"id":"D5","name":"Coupling","shortDescription":{"text":"Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D5"},{"id":"D6","name":"Cohesion (LCOM4)","shortDescription":{"text":"Cohesion (LCOM4)"},"helpUri":"https://codehealth.canine.dev/dimensions/D6"},{"id":"D8","name":"Code Coverage","shortDescription":{"text":"Code Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/D8"},{"id":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"id":"D10","name":"Test Quality","shortDescription":{"text":"Test Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D10"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D18","name":"Solution Shape","shortDescription":{"text":"Solution Shape"},"helpUri":"https://codehealth.canine.dev/dimensions/D18"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"D20","name":"ADR Quality","shortDescription":{"text":"ADR Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D20"},{"id":"D21","name":"Naming Consistency","shortDescription":{"text":"Naming Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D21"},{"id":"D22","name":"Internal API Consistency","shortDescription":{"text":"Internal API Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D22"},{"id":"D23","name":"Boundary Type-Coupling","shortDescription":{"text":"Boundary Type-Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D23"},{"id":"D24","name":"Comment Value","shortDescription":{"text":"Comment Value"},"helpUri":"https://codehealth.canine.dev/dimensions/D24"},{"id":"D26","name":"Project Cohesion","shortDescription":{"text":"Project Cohesion"},"helpUri":"https://codehealth.canine.dev/dimensions/D26"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"]}},{"id":"D30","name":"Dependency Vulnerabilities","shortDescription":{"text":"Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D30","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"]}},{"id":"D31","name":"IaC \u0026 Container Security","shortDescription":{"text":"IaC \u0026 Container Security"},"helpUri":"https://codehealth.canine.dev/dimensions/D31","relationships":[{"target":{"id":"CWE-1032","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-16","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1032","CWE-732","CWE-16"]}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"D36","name":"Supply-chain Provenance \u0026 Signing","shortDescription":{"text":"Supply-chain Provenance \u0026 Signing"},"helpUri":"https://codehealth.canine.dev/dimensions/D36","relationships":[{"target":{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"]}},{"id":"D37","name":"Vulnerability-disclosure Policy","shortDescription":{"text":"Vulnerability-disclosure Policy"},"helpUri":"https://codehealth.canine.dev/dimensions/D37","relationships":[{"target":{"id":"CWE-1059","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1059"]}},{"id":"D43","name":"Malicious Dependencies","shortDescription":{"text":"Malicious Dependencies"},"helpUri":"https://codehealth.canine.dev/dimensions/D43","relationships":[{"target":{"id":"CWE-506","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-506"]}},{"id":"D44","name":"Platform End-of-Life","shortDescription":{"text":"Platform End-of-Life"},"helpUri":"https://codehealth.canine.dev/dimensions/D44"},{"id":"AC1","name":"Text alternatives","shortDescription":{"text":"Text alternatives"},"helpUri":"https://codehealth.canine.dev/dimensions/AC1"},{"id":"AC2","name":"Forms \u0026 labels","shortDescription":{"text":"Forms \u0026 labels"},"helpUri":"https://codehealth.canine.dev/dimensions/AC2"},{"id":"AC3","name":"Page structure","shortDescription":{"text":"Page structure"},"helpUri":"https://codehealth.canine.dev/dimensions/AC3"},{"id":"AC5","name":"ARIA correctness","shortDescription":{"text":"ARIA correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/AC5"},{"id":"AC6","name":"Visual \u0026 motion safety","shortDescription":{"text":"Visual \u0026 motion safety"},"helpUri":"https://codehealth.canine.dev/dimensions/AC6"},{"id":"AC7","name":"A11y enforcement","shortDescription":{"text":"A11y enforcement"},"helpUri":"https://codehealth.canine.dev/dimensions/AC7"},{"id":"AX1","name":"Captive dependencies","shortDescription":{"text":"Captive dependencies"},"helpUri":"https://codehealth.canine.dev/dimensions/AX1"},{"id":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"id":"AX2","name":"Stateful singletons","shortDescription":{"text":"Stateful singletons"},"helpUri":"https://codehealth.canine.dev/dimensions/AX2"},{"id":"AX3","name":"Project dependency cycles","shortDescription":{"text":"Project dependency cycles"},"helpUri":"https://codehealth.canine.dev/dimensions/AX3"},{"id":"AX5","name":"Architecture \u0026 structure","shortDescription":{"text":"Architecture \u0026 structure"},"helpUri":"https://codehealth.canine.dev/dimensions/AX5"},{"id":"AX6","name":"Interface segregation","shortDescription":{"text":"Interface segregation"},"helpUri":"https://codehealth.canine.dev/dimensions/AX6"},{"id":"AX7","name":"Slice cohesion","shortDescription":{"text":"Slice cohesion"},"helpUri":"https://codehealth.canine.dev/dimensions/AX7"},{"id":"AX8","name":"Test isolation","shortDescription":{"text":"Test isolation"},"helpUri":"https://codehealth.canine.dev/dimensions/AX8"},{"id":"AX9","name":"CQS / query purity","shortDescription":{"text":"CQS / query purity"},"helpUri":"https://codehealth.canine.dev/dimensions/AX9"},{"id":"AXB2","name":"Runtime readiness","shortDescription":{"text":"Runtime readiness"},"helpUri":"https://codehealth.canine.dev/dimensions/AXB2"},{"id":"C1","name":"Data Protection","shortDescription":{"text":"Data Protection"},"helpUri":"https://codehealth.canine.dev/dimensions/C1"},{"id":"C2","name":"Access Controls","shortDescription":{"text":"Access Controls"},"helpUri":"https://codehealth.canine.dev/dimensions/C2"},{"id":"C3","name":"Audit Trail","shortDescription":{"text":"Audit Trail"},"helpUri":"https://codehealth.canine.dev/dimensions/C3"},{"id":"C4","name":"Data Retention","shortDescription":{"text":"Data Retention"},"helpUri":"https://codehealth.canine.dev/dimensions/C4"},{"id":"DM1","name":"Aggregate boundaries","shortDescription":{"text":"Aggregate boundaries"},"helpUri":"https://codehealth.canine.dev/dimensions/DM1"},{"id":"DM10","name":"One transaction, one aggregate","shortDescription":{"text":"One transaction, one aggregate"},"helpUri":"https://codehealth.canine.dev/dimensions/DM10"},{"id":"DM11","name":"Constructible invalid state","shortDescription":{"text":"Constructible invalid state"},"helpUri":"https://codehealth.canine.dev/dimensions/DM11"},{"id":"DM4","name":"Rich vs anemic model","shortDescription":{"text":"Rich vs anemic model"},"helpUri":"https://codehealth.canine.dev/dimensions/DM4"},{"id":"DM5","name":"Encapsulated state","shortDescription":{"text":"Encapsulated state"},"helpUri":"https://codehealth.canine.dev/dimensions/DM5"},{"id":"DM8","name":"Value-object opportunities","shortDescription":{"text":"Value-object opportunities"},"helpUri":"https://codehealth.canine.dev/dimensions/DM8"},{"id":"DM9","name":"Scattered domain decisions","shortDescription":{"text":"Scattered domain decisions"},"helpUri":"https://codehealth.canine.dev/dimensions/DM9"},{"id":"ED5","name":"Idempotency","shortDescription":{"text":"Idempotency"},"helpUri":"https://codehealth.canine.dev/dimensions/ED5"},{"id":"GD1","name":"Unfinished \u0026 placeholder code","shortDescription":{"text":"Unfinished \u0026 placeholder code"},"helpUri":"https://codehealth.canine.dev/dimensions/GD1"},{"id":"IC1","name":"Incompleteness \u0026 stubs","shortDescription":{"text":"Incompleteness \u0026 stubs"},"helpUri":"https://codehealth.canine.dev/dimensions/IC1"},{"id":"M1","name":"Documentation (README)","shortDescription":{"text":"Documentation (README)"},"helpUri":"https://codehealth.canine.dev/dimensions/M1"},{"id":"M2","name":"Architecture documentation","shortDescription":{"text":"Architecture documentation"},"helpUri":"https://codehealth.canine.dev/dimensions/M2"},{"id":"M3","name":"Folder \u0026 project structure","shortDescription":{"text":"Folder \u0026 project structure"},"helpUri":"https://codehealth.canine.dev/dimensions/M3"},{"id":"M4","name":"Documentation accuracy","shortDescription":{"text":"Documentation accuracy"},"helpUri":"https://codehealth.canine.dev/dimensions/M4"},{"id":"P1","name":"CI/CD gates","shortDescription":{"text":"CI/CD gates"},"helpUri":"https://codehealth.canine.dev/dimensions/P1"},{"id":"P10","name":"Library API \u0026 versioning","shortDescription":{"text":"Library API \u0026 versioning"},"helpUri":"https://codehealth.canine.dev/dimensions/P10"},{"id":"P12","name":"CI test-gate honesty","shortDescription":{"text":"CI test-gate honesty"},"helpUri":"https://codehealth.canine.dev/dimensions/P12"},{"id":"P2","name":"Observability","shortDescription":{"text":"Observability"},"helpUri":"https://codehealth.canine.dev/dimensions/P2"},{"id":"P3","name":"Security \u0026 performance tooling","shortDescription":{"text":"Security \u0026 performance tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/P3"},{"id":"P4","name":"Deployment \u0026 Rollback","shortDescription":{"text":"Deployment \u0026 Rollback"},"helpUri":"https://codehealth.canine.dev/dimensions/P4"},{"id":"P5","name":"DR \u0026 Backup","shortDescription":{"text":"DR \u0026 Backup"},"helpUri":"https://codehealth.canine.dev/dimensions/P5"},{"id":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"id":"P7","name":"Outbound HTTP resilience","shortDescription":{"text":"Outbound HTTP resilience"},"helpUri":"https://codehealth.canine.dev/dimensions/P7"},{"id":"P8","name":"Schema migrations","shortDescription":{"text":"Schema migrations"},"helpUri":"https://codehealth.canine.dev/dimensions/P8"},{"id":"PF1","name":"Benchmark discipline","shortDescription":{"text":"Benchmark discipline"},"helpUri":"https://codehealth.canine.dev/dimensions/PF1"},{"id":"PF2","name":"Allocation hygiene","shortDescription":{"text":"Allocation hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/PF2"},{"id":"PF3","name":"Async \u0026 latency hygiene","shortDescription":{"text":"Async \u0026 latency hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/PF3"},{"id":"R1","name":"Type Safety","shortDescription":{"text":"Type Safety"},"helpUri":"https://codehealth.canine.dev/dimensions/R1"},{"id":"R10","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/R10"},{"id":"R2","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/R2"},{"id":"R3","name":"Large Files","shortDescription":{"text":"Large Files"},"helpUri":"https://codehealth.canine.dev/dimensions/R3"},{"id":"R4","name":"Test Coverage","shortDescription":{"text":"Test Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/R4"},{"id":"R5","name":"Dependency Freshness","shortDescription":{"text":"Dependency Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/R5"},{"id":"R6","name":"Tooling","shortDescription":{"text":"Tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/R6"},{"id":"R7","name":"Dead Code","shortDescription":{"text":"Dead Code"},"helpUri":"https://codehealth.canine.dev/dimensions/R7"},{"id":"R8","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/R8"},{"id":"R9","name":"Circular Imports","shortDescription":{"text":"Circular Imports"},"helpUri":"https://codehealth.canine.dev/dimensions/R9"},{"id":"S1","name":"Web-Security Posture","shortDescription":{"text":"Web-Security Posture"},"helpUri":"https://codehealth.canine.dev/dimensions/S1"},{"id":"SC1","name":"Supply-chain hygiene","shortDescription":{"text":"Supply-chain hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/SC1"},{"id":"X1","name":"Async correctness","shortDescription":{"text":"Async correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/X1"},{"id":"X10","name":"Duplicated predicate","shortDescription":{"text":"Duplicated predicate"},"helpUri":"https://codehealth.canine.dev/dimensions/X10"},{"id":"X12","name":"Unreachable branch","shortDescription":{"text":"Unreachable branch"},"helpUri":"https://codehealth.canine.dev/dimensions/X12"},{"id":"X13","name":"Undrained process stream","shortDescription":{"text":"Undrained process stream"},"helpUri":"https://codehealth.canine.dev/dimensions/X13"},{"id":"X16","name":"Unfloored truncation loop","shortDescription":{"text":"Unfloored truncation loop"},"helpUri":"https://codehealth.canine.dev/dimensions/X16"},{"id":"X18","name":"Disposal-pattern correctness","shortDescription":{"text":"Disposal-pattern correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/X18"},{"id":"X19","name":"Unrestored process-global state","shortDescription":{"text":"Unrestored process-global state"},"helpUri":"https://codehealth.canine.dev/dimensions/X19"},{"id":"X2","name":"Cancellation propagation","shortDescription":{"text":"Cancellation propagation"},"helpUri":"https://codehealth.canine.dev/dimensions/X2"},{"id":"X20","name":"Mistyped argument guard","shortDescription":{"text":"Mistyped argument guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X20"},{"id":"X21","name":"Side-effecting pattern guard","shortDescription":{"text":"Side-effecting pattern guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X21"},{"id":"X22","name":"Contradicted release guard","shortDescription":{"text":"Contradicted release guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X22"},{"id":"X23","name":"Unguarded diagnostic materialisation","shortDescription":{"text":"Unguarded diagnostic materialisation"},"helpUri":"https://codehealth.canine.dev/dimensions/X23"},{"id":"X25","name":"Inert configuration knob","shortDescription":{"text":"Inert configuration knob"},"helpUri":"https://codehealth.canine.dev/dimensions/X25"},{"id":"X26","name":"Unsynchronised callback handoff","shortDescription":{"text":"Unsynchronised callback handoff"},"helpUri":"https://codehealth.canine.dev/dimensions/X26"},{"id":"X27","name":"Collection changed while being enumerated","shortDescription":{"text":"Collection changed while being enumerated"},"helpUri":"https://codehealth.canine.dev/dimensions/X27"},{"id":"X28","name":"Index access outside its own emptiness guard","shortDescription":{"text":"Index access outside its own emptiness guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X28"},{"id":"X29","name":"Per-element action decided by a fixed element","shortDescription":{"text":"Per-element action decided by a fixed element"},"helpUri":"https://codehealth.canine.dev/dimensions/X29"},{"id":"X3","name":"Exception handling","shortDescription":{"text":"Exception handling"},"helpUri":"https://codehealth.canine.dev/dimensions/X3"},{"id":"X30","name":"Support guard that admits what it rejects","shortDescription":{"text":"Support guard that admits what it rejects"},"helpUri":"https://codehealth.canine.dev/dimensions/X30"},{"id":"X32","name":"Type resolved by simple name across every loaded assembly","shortDescription":{"text":"Type resolved by simple name across every loaded assembly"},"helpUri":"https://codehealth.canine.dev/dimensions/X32"},{"id":"X4","name":"Structured logging","shortDescription":{"text":"Structured logging"},"helpUri":"https://codehealth.canine.dev/dimensions/X4"},{"id":"X5","name":"Nullable reference types","shortDescription":{"text":"Nullable reference types"},"helpUri":"https://codehealth.canine.dev/dimensions/X5"},{"id":"X6","name":"Hand-rolled structured-format parsing","shortDescription":{"text":"Hand-rolled structured-format parsing"},"helpUri":"https://codehealth.canine.dev/dimensions/X6"},{"id":"X7","name":"Silent fallback defaults","shortDescription":{"text":"Silent fallback defaults"},"helpUri":"https://codehealth.canine.dev/dimensions/X7"},{"id":"X8","name":"JS interop contract","shortDescription":{"text":"JS interop contract"},"helpUri":"https://codehealth.canine.dev/dimensions/X8"},{"id":"X9","name":"Subsumed condition operand","shortDescription":{"text":"Subsumed condition operand"},"helpUri":"https://codehealth.canine.dev/dimensions/X9"}]}},"results":[{"ruleId":"D1","level":"warning","message":{"text":"rask-morph.morph (cyclomatic 77): rask-morph.morph has cyclomatic complexity 77 (threshold 15). Of this number, 74 points are the body\u0027s own statements and 3 belong to 2 function literals inside it that branch. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c69ce2747e8a81fbabcfe1deaa07fc162ddc669f542f70d3512933db9deaf25"}},{"ruleId":"D1","level":"warning","message":{"text":"ModelInputGenerator.Render (cyclomatic 62): ModelInputGenerator.Render has cyclomatic complexity 62 (threshold 15). Of this number, 61 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":686}}}],"partialFingerprints":{"codehealthFindingId/v1":"190525344d4569a8dad4ae4cf493c8f1248cd4d2a5030589eeffe54dcca621cd"}},{"ruleId":"D1","level":"warning","message":{"text":"HtmlSerializer.Serialize (cyclomatic 58): HtmlSerializer.Serialize has cyclomatic complexity 58 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/HtmlSerializer.cs"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0325619b89e0fe61abea7d9873e1d16de110c83932dc252ce566cf8230d35f5"}},{"ruleId":"D1","level":"warning","message":{"text":"Input.WriteAttributes (cyclomatic 53): Input.WriteAttributes has cyclomatic complexity 53 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Input.cs"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef060b478fbe4ef6683a5b0609c679eda1bad2179a4c6523fcd0833ac77a41d2"}},{"ruleId":"D1","level":"warning","message":{"text":"panel-client.installPanelClient (cyclomatic 52): panel-client.installPanelClient has cyclomatic complexity 52 (threshold 15). Most of this is not in the body itself: 2 of the 52 points are its own statements and the rest belongs to 10 function literals inside it that branch (lines 201, 147, 66, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/panel/panel-client.ts"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"b82cfd6327f2ad347eb4819c861d4179f17e29cef6bc59fcc90be927d460d92a"}},{"ruleId":"D1","level":"warning","message":{"text":"DeployCommand.ExecuteAsync (cyclomatic 44): DeployCommand.ExecuteAsync has cyclomatic complexity 44 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DeployCommand.cs"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6a589a3e7b2a6d963529b3dab00131dcc845b5dd5cd2908c1ec7c6ba80f79bd"}},{"ruleId":"D1","level":"warning","message":{"text":"Component.TryInvokeHandlerCoreAsync (cyclomatic 43): Component.TryInvokeHandlerCoreAsync has cyclomatic complexity 43 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":2270}}}],"partialFingerprints":{"codehealthFindingId/v1":"59a604c84656ae36e48ee200e393d7a7769c126746c1f4a59b703d343a694f36"}},{"ruleId":"D1","level":"warning","message":{"text":"ExternalGenerator.Emit (cyclomatic 41): ExternalGenerator.Emit has cyclomatic complexity 41 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":792}}}],"partialFingerprints":{"codehealthFindingId/v1":"05ff5fe6649e15826f336625441b5ed0961ed65e359466ed1bad9df46928c9ee"}},{"ruleId":"D1","level":"warning","message":{"text":"ContentSniffer.Signature (cyclomatic 41): ContentSniffer.Signature has cyclomatic complexity 41 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Upload/ContentSniffer.cs"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0e489716708fa9c7b9461d1d225c8ad28014fafe83e64213433d92c711868e0"}},{"ruleId":"D1","level":"warning","message":{"text":"RaskEndpointExtensions.RunSocketLoop (cyclomatic 40): RaskEndpointExtensions.RunSocketLoop has cyclomatic complexity 40 (threshold 15). Of this number, 39 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1357}}}],"partialFingerprints":{"codehealthFindingId/v1":"f06082b065d0dad2bdf5e51dc31dc9b60db77c2a943e78c7d4a19dfad4be4dd4"}},{"ruleId":"D1","level":"warning","message":{"text":"LivePayload.BuildPayloadUtf8Diff (cyclomatic 38): LivePayload.BuildPayloadUtf8Diff has cyclomatic complexity 38 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"b30514e2002811d0c64291de457719f2f280ae108b214110de73d7572b561922"}},{"ruleId":"D1","level":"warning","message":{"text":"CssScoper.AppendScopedSelector (cyclomatic 37): CssScoper.AppendScopedSelector has cyclomatic complexity 37 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function, or replace a long branch ladder over a single value with a data-driven lookup or dispatch table."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedCss/CssScoper.cs"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0b266d2cbf4ae7c33bb53b74d08e0804317113e52c973ef48e4c8a264481a40"}},{"ruleId":"D1","level":"warning","message":{"text":"rask-dom.applyDiff (cyclomatic 36): rask-dom.applyDiff has cyclomatic complexity 36 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"eccd354cfa1871b97caa7954cbb4390d00f7890e5f4ac4ef5ce7175ad2c6e59c"}},{"ruleId":"D1","level":"warning","message":{"text":"TypeWalker.serialize (cyclomatic 36): TypeWalker.serialize has cyclomatic complexity 36 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":499}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfa0272ba8377cb0bc6ca5afe1f153630f6a8ae28dbc84431e99554ce6397079"}},{"ruleId":"D1","level":"warning","message":{"text":"ComponentFactoryGenerator.GetFactoryProperties (cyclomatic 33): ComponentFactoryGenerator.GetFactoryProperties has cyclomatic complexity 33 (threshold 15). Of this number, 31 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":5119}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9c839eef97c5b020f870c3ee4ae810f33cadac40c97c9aefe3b09bce6383379"}},{"ruleId":"D1","level":"warning","message":{"text":"client.httpTransport (cyclomatic 33): client.httpTransport has cyclomatic complexity 33 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/client/client.ts"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e3bb14bece01bac23ae9e7ffaa329216206a4333b68c4251a207593f70a85c1"}},{"ruleId":"D1","level":"warning","message":{"text":"DbCommand.ExecuteAsync (cyclomatic 32): DbCommand.ExecuteAsync has cyclomatic complexity 32 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DbCommand.cs"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"7daa64045141939755258bc5ed6f093a2e245a478b8dc3e4496539a816b3d54e"}},{"ruleId":"D1","level":"warning","message":{"text":"affected_projects.main (cyclomatic 31): affected_projects.main has cyclomatic complexity 31 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/lib/affected_projects.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"f42bb78858e8c3968d18a8cd88563ac34ad6b681d9e776b393b6f2d29741de7c"}},{"ruleId":"D1","level":"warning","message":{"text":"rask-http-transport.openHttpConnection (cyclomatic 31): rask-http-transport.openHttpConnection has cyclomatic complexity 31 (threshold 15). Most of this is not in the body itself: 12 of the 31 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 356, 396, 353). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask-http-transport.ts"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"79933d0643c929c319802563214429cd1e25db91e3a5f8190b8cea2ac36e65d8"}},{"ruleId":"D1","level":"warning","message":{"text":"NewCommand.ExecuteAsync (cyclomatic 30): NewCommand.ExecuteAsync has cyclomatic complexity 30 (threshold 15). Of this number, 25 points are the body\u0027s own statements and 5 belong to one function literal inside it that branches. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bb644b9c5a935511125069f45a9d6f5a4bd6e4a3af08237e2cca81857d1ad33"}},{"ruleId":"D1","level":"warning","message":{"text":"NewCommand.GenerateDirectAsync (cyclomatic 30): NewCommand.GenerateDirectAsync has cyclomatic complexity 30 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":681}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef77e568d703d9480801f5121c27b410dc57f4091dede30a25d8256f4293f63d"}},{"ruleId":"D1","level":"warning","message":{"text":"extract-props.extractIsland (cyclomatic 29): extract-props.extractIsland has cyclomatic complexity 29 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8ab59fb9290b5d6d11b72c95c63fa3dc63ed275e412accfd893827a0d542d41"}},{"ruleId":"D1","level":"warning","message":{"text":"ComponentFactoryGenerator.EmitConsumerEntries (cyclomatic 28): ComponentFactoryGenerator.EmitConsumerEntries has cyclomatic complexity 28 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":3417}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f7500afb8945ba47ca06812931dba6b947930a7c6fa07529cee68c578f15f46"}},{"ruleId":"D1","level":"warning","message":{"text":"EditContext.ValidateFieldAsync (cyclomatic 27): EditContext.ValidateFieldAsync has cyclomatic complexity 27 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/EditContext.cs"},"region":{"startLine":716}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ac1e8f06f189faefc4cd4778336b28f7022cf30c21d432772500b8c713c6bd9"}},{"ruleId":"D1","level":"warning","message":{"text":"HostFacts.Parse (cyclomatic 26): HostFacts.Parse has cyclomatic complexity 26 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/HostProbe.cs"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a9e3a96524dfa9ce6c990fa2c4cfd5b4b3ba885d8812573b452af72fdf1d6ac"}},{"ruleId":"D1","level":"warning","message":{"text":"FrameDiffer.DiffKeyedSiblings (cyclomatic 26): FrameDiffer.DiffKeyedSiblings has cyclomatic complexity 26 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":814}}}],"partialFingerprints":{"codehealthFindingId/v1":"c29895f3c05373de2a94414065ab99b73aa485b00cced55d8ac855aeed4b58df"}},{"ruleId":"D1","level":"warning","message":{"text":"ExternalPackageScan.Blank (cyclomatic 26): ExternalPackageScan.Blank has cyclomatic complexity 26 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageScan.cs"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0f4e90dc81ec01adb68b26adb80ec5ab312d72262c5cf1593311a57b0cb3711"}},{"ruleId":"D1","level":"warning","message":{"text":"RoutesGenerator.Emit (cyclomatic 26): RoutesGenerator.Emit has cyclomatic complexity 26 (threshold 15). Of this number, 25 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":649}}}],"partialFingerprints":{"codehealthFindingId/v1":"f848c820e77e537556ff4c372f4759ea79e1cf81b7c7f4f92ab42fd2cdd92321"}},{"ruleId":"D1","level":"warning","message":{"text":"BakeScopedAssetsTask.BakeFromAssemblies (cyclomatic 26): BakeScopedAssetsTask.BakeFromAssemblies has cyclomatic complexity 26 (threshold 15). Of this number, 22 points are the body\u0027s own statements and 4 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6f52a30cd1f0f5ce5cb60e03dfe6f25afdb57f68f5aebcc410032d2e09fcdf5"}},{"ruleId":"D1","level":"warning","message":{"text":"extract-props.extractAngular (cyclomatic 26): extract-props.extractAngular has cyclomatic complexity 26 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":1188}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fa004f58b95aebc374836be5b69695b65a2f248b231e880dde07ed5a65823e3"}},{"ruleId":"D1","level":"warning","message":{"text":"ValueObjectCollector.Of (cyclomatic 25): ValueObjectCollector.Of has cyclomatic complexity 25 (threshold 15). Of this number, 17 points are the body\u0027s own statements and 8 belong to 4 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/GeneratedModelShape.cs"},"region":{"startLine":798}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ab136cf8bd8b671f17e384e2294767304c12a27a290e7db5415105949543f50"}},{"ruleId":"D1","level":"warning","message":{"text":"Element.WriteAttributes (cyclomatic 25): Element.WriteAttributes has cyclomatic complexity 25 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Element.cs"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"9db81b800dc4e5b5b9fbb7e4fd9aa4bc060364dcc466f014fc9bd40fe197c1dd"}},{"ruleId":"D1","level":"warning","message":{"text":"FrameDiffer.DiffSiblings (cyclomatic 25): FrameDiffer.DiffSiblings has cyclomatic complexity 25 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"e914d15ab97a1360dbfd90dae468cd6582e59883c806f68cd7bd6b44f9ccfe50"}},{"ruleId":"D1","level":"warning","message":{"text":"overlay.installOverlay (cyclomatic 25): overlay.installOverlay has cyclomatic complexity 25 (threshold 15). Most of this is not in the body itself: 6 of the 25 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 127, 95, 115, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/overlay.ts"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"00ad3e9627009b697bcca7e008be4be173014a28b30b077f1c04cb3c2277b484"}},{"ruleId":"D1","level":"warning","message":{"text":"extract-props.extractLit (cyclomatic 25): extract-props.extractLit has cyclomatic complexity 25 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":941}}}],"partialFingerprints":{"codehealthFindingId/v1":"8624b1aa4dcda36766b47ae0ac0986f623dc1dd579561dfdc75f213b57b3e78b"}},{"ruleId":"D1","level":"warning","message":{"text":"rask.applyFullReply (cyclomatic 25): rask.applyFullReply has cyclomatic complexity 25 (threshold 15). Most of this is not in the body itself: 4 of the 25 points are its own statements and the rest belongs to one function literal inside it that branches (line 1496). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1489}}}],"partialFingerprints":{"codehealthFindingId/v1":"798a052340a3e169233a44ffbba90f85a56cafe50b2a935bf1622e63c26d552f"}},{"ruleId":"D1","level":"warning","message":{"text":"CssScoper.RewriteBlock (cyclomatic 24): CssScoper.RewriteBlock has cyclomatic complexity 24 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedCss/CssScoper.cs"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"6684e0147b9e5878ff7b406110f616bc3ad807751ef3fa6b3d62cb9ac04c5cb4"}},{"ruleId":"D1","level":"warning","message":{"text":"PropsSnapshotReader.ReadType (cyclomatic 24): PropsSnapshotReader.ReadType has cyclomatic complexity 24 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function, or replace a long branch ladder over a single value with a data-driven lookup or dispatch table."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PropsSnapshotReader.cs"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c5db8d7ab594afd413c5c5e82cd314560158b8cc128ffb1fc5e888720c8a280"}},{"ruleId":"D1","level":"warning","message":{"text":"UiSelect.OnKeyAsync (cyclomatic 24): UiSelect.OnKeyAsync has cyclomatic complexity 24 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiSelect.cs"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b6fe37aeb02dbd3b8fa094803547a7a937854d5148c0939514fcb0ec8681747"}},{"ruleId":"D1","level":"warning","message":{"text":"ExternalPackageScan.ReadLiteral (cyclomatic 23): ExternalPackageScan.ReadLiteral has cyclomatic complexity 23 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageScan.cs"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"17dd0c66f960d812777ed8147c28d03bac8eb9717cee20321e3d7a9b2546ae48"}},{"ruleId":"D1","level":"warning","message":{"text":"WriteExternalBuildInputsTask.Execute (cyclomatic 23): WriteExternalBuildInputsTask.Execute has cyclomatic complexity 23 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/WriteExternalBuildInputsTask.cs"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf3c80f56a20692521281607fb5e4266cd4c7aa412a4ff47dd6abc4bc993490f"}},{"ruleId":"D1","level":"warning","message":{"text":"UiKitDataInputDemo.Render (cyclomatic 23): UiKitDataInputDemo.Render has cyclomatic complexity 23 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 7 belong to 5 function literals inside it that branch. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a8c1065cee32b68fb01bde976df57897a78a896c8c74a5a39025dda7ae093d3"}},{"ruleId":"D1","level":"warning","message":{"text":"ContentSniffer.IsoMedia (cyclomatic 23): ContentSniffer.IsoMedia has cyclomatic complexity 23 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Upload/ContentSniffer.cs"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"14dceeaaa5b91a620b5671fcb1f52caf24e38cb5fc84a62c904f5c367136d77e"}},{"ruleId":"D1","level":"warning","message":{"text":"HtmlTree.TryReadStartTag (cyclomatic 23): HtmlTree.TryReadStartTag has cyclomatic complexity 23 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function, or replace a long branch ladder over a single value with a data-driven lookup or dispatch table."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Testing/HtmlTree.cs"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"b355cc9be4d948d892ac278bbd2d8f246d15a8416737b75ee6d5d7c93fb982db"}},{"ruleId":"D1","level":"warning","message":{"text":"rask.wasm.trackHeadAsset (cyclomatic 23): rask.wasm.trackHeadAsset has cyclomatic complexity 23 (threshold 15). Of this number, 19 points are the body\u0027s own statements and 4 belong to one function literal inside it that branches. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask.wasm.ts"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"66a57f893a2cb09bb0eacd426f8d25be517e951cd4bc9b78852663fc6ea2e19e"}},{"ruleId":"D1","level":"warning","message":{"text":"HostSetup.EnsureReadyAsync (cyclomatic 22): HostSetup.EnsureReadyAsync has cyclomatic complexity 22 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/HostSetup.cs"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"0481177180c5111bd0c3430b8a5dd191813e6a31e30dd1b1a9038bec1e3c9cd4"}},{"ruleId":"D1","level":"warning","message":{"text":"LiveSessionBase.WritePayload (cyclomatic 22): LiveSessionBase.WritePayload has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LiveSessionBase.cs"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"71bd661e9077636ee7298630cefcf1cb8383d4128f41a333a3bb0d9b002dceb7"}},{"ruleId":"D1","level":"warning","message":{"text":"MessageParser.Parse (cyclomatic 22): MessageParser.Parse has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/MessageParser.cs"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba43ddad99bc3098f6c4a8ebee3bb07e789b2c5f06478cbae33425691903386b"}},{"ruleId":"D1","level":"warning","message":{"text":"TranslationCatalogGenerator.EmitFamily (cyclomatic 22): TranslationCatalogGenerator.EmitFamily has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/TranslationCatalogGenerator.cs"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bd73714ee66376eeafbecf118baea9e3e673a37f31cbf14ee5a52f397be3916"}},{"ruleId":"D1","level":"warning","message":{"text":"RaskEndpointExtensions.UseRask (cyclomatic 22): RaskEndpointExtensions.UseRask has cyclomatic complexity 22 (threshold 15). Most of this is not in the body itself: 9 of the 22 points are its own statements and the rest belongs to one function literal inside it that branches (line 521). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":455}}}],"partialFingerprints":{"codehealthFindingId/v1":"200c7eab906e2d3aa3d4fa31343e5efdd0b4606976902d93f3bca4f88f7b7569"}},{"ruleId":"D1","level":"warning","message":{"text":"WasmPrerender.PatchManifest (cyclomatic 22): WasmPrerender.PatchManifest has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/WasmPrerender.cs"},"region":{"startLine":414}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ed10c4b45e6386c7761a74a02f4fd285b5e04835c44227cedb5bbe2213a0496"}},{"ruleId":"D1","level":"warning","message":{"text":"RaskBatteryWiring.Apply (cyclomatic 22): RaskBatteryWiring.Apply has cyclomatic complexity 22 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskBatteryWiring.cs"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"066a773f96f97b9256a89fbf76d4a7b0a4aaa1e1d2e201bc756d3477f427cc72"}},{"ruleId":"D1","level":"warning","message":{"text":"ArgumentSchema.Parse (cyclomatic 21): ArgumentSchema.Parse has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/ArgumentSchema.cs"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f883b3fccce4a93b60c9e3b9c6e64ce6da0f6b4b065b5ba391cc51b767924cc"}},{"ruleId":"D1","level":"warning","message":{"text":"Component.RenderForLive (cyclomatic 21): Component.RenderForLive has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":1253}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4be7b80d39ad6c8b396e235c2aa3a8f3c83851b93bcc5c4fc0d96a3925fb216"}},{"ruleId":"D1","level":"warning","message":{"text":"Textarea.WriteAttributes (cyclomatic 21): Textarea.WriteAttributes has cyclomatic complexity 21 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Textarea.cs"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed1414eeb4bf82fd889749d0a8c62eb6eef6f09c3aa55da1a861580df0d55823"}},{"ruleId":"D1","level":"warning","message":{"text":"BuilderEntry.TryReadChain (cyclomatic 21): BuilderEntry.TryReadChain has cyclomatic complexity 21 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function, or replace a long branch ladder over a single value with a data-driven lookup or dispatch table."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/BuilderEntry.cs"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6b17df56aa2fc70b7bb37791953c3a8f5e366183655d6e487884014aec857a4"}},{"ruleId":"D1","level":"warning","message":{"text":"AzureAccount.Parse (cyclomatic 21): AzureAccount.Parse has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Backends/AzureAccount.cs"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"966761096a322eb4adf93ef0376985e72c53afe7cf909490fe7a906545855b32"}},{"ruleId":"D1","level":"warning","message":{"text":"UiTree.OnKeyAsync (cyclomatic 21): UiTree.OnKeyAsync has cyclomatic complexity 21 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiTree.cs"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c8ba45cf06ca6b274643e03789c1d2473a4591f7ca59d2f83d4436db6a54ede"}},{"ruleId":"D1","level":"warning","message":{"text":"angular.renderChildren (cyclomatic 21): angular.renderChildren has cyclomatic complexity 21 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/angular.ts"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"85ecc2f67605c0e2a58baa78a9b8eb26728eb704d57234ff216aafaea4805349"}},{"ruleId":"D1","level":"warning","message":{"text":"WireShape.Classify (cyclomatic 20): WireShape.Classify has cyclomatic complexity 20 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/WireShape.cs"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4028ad70f03e16ebeae34652d3299d699c1919f94f292f3e79ef1fd4f231bce"}},{"ruleId":"D1","level":"warning","message":{"text":"CssMinifier.Minify (cyclomatic 20): CssMinifier.Minify has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedAssets/CssMinifier.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"063c3cdd4448073e2a23ba566f278baa2e922c341bf407ff0110e2a52175b838"}},{"ruleId":"D1","level":"warning","message":{"text":"BlazorParameters.Read (cyclomatic 20): BlazorParameters.Read has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Blazor/BlazorParameters.cs"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cdc99f3db17d8a9053d13fd9414065589f1a60254bc3f91fbf3b226ea8e89b9"}},{"ruleId":"D1","level":"warning","message":{"text":"RaskSpaEndpointExtensions.UseRaskSpa (cyclomatic 20): RaskSpaEndpointExtensions.UseRaskSpa has cyclomatic complexity 20 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 4 belong to 2 function literals inside it that branch. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/RaskSpaEndpointExtensions.cs"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"29983e83ef05cc936040cab08e39e3efe9f3f27eda6711af5106a09ffdbb3e01"}},{"ruleId":"D1","level":"warning","message":{"text":"UiSelect.Custom (cyclomatic 20): UiSelect.Custom has cyclomatic complexity 20 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiSelect.cs"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6ec40c0a110bce9fd1224b9d401241b00146c4d225cbbe254327a77d527d520"}},{"ruleId":"D1","level":"warning","message":{"text":"rask-deverror.showDevError (cyclomatic 20): rask-deverror.showDevError has cyclomatic complexity 20 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-deverror.ts"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1e5022dad809cb227cee262c14ba167c2709ded9b6db2205a945eab7d1b8188"}},{"ruleId":"D1","level":"warning","message":{"text":"lit.renderChildren (cyclomatic 20): lit.renderChildren has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/lit.ts"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bdd9b1644ad53b106b94cf8f139f3085c69b3e3df8275d1bb8b25f2765c2af4"}},{"ruleId":"D1","level":"warning","message":{"text":"CqrsDispatchGenerator.GetCandidate (cyclomatic 19): CqrsDispatchGenerator.GetCandidate has cyclomatic complexity 19 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsDispatchGenerator.cs"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ed859ac7e799bd6863a540e249a01081165cd4eadd3c07291fd9f28ef20a590"}},{"ruleId":"D1","level":"warning","message":{"text":"BulkInsertPlan.Build (cyclomatic 19): BulkInsertPlan.Build has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/BulkInsertPlan.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"b551213cedb7e4237a6808bbbf3e40dd9a84fac9d4ee3190abcc472d0d5539a8"}},{"ruleId":"D1","level":"warning","message":{"text":"ReadModelRegistry.MapColumns (cyclomatic 19): ReadModelRegistry.MapColumns has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/ReadModelRegistry.cs"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"1903016e0b93adcbe7026462b1d6807a94e2ed1c2c6a1239882076926308c210"}},{"ruleId":"D1","level":"warning","message":{"text":"PackageIslandProps.Facts (cyclomatic 19): PackageIslandProps.Facts has cyclomatic complexity 19 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function, or replace a long branch ladder over a single value with a data-driven lookup or dispatch table."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PackageIslandProps.cs"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"472e668cd74243209037477e761c37a83594f91ca3124fd6c0536c7d7dfc59fd"}},{"ruleId":"D1","level":"warning","message":{"text":"Resolver.Map (cyclomatic 19): Resolver.Map has cyclomatic complexity 19 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PackageIslandProps.cs"},"region":{"startLine":634}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb116afa9b4fcc4384944e7bf257cbdaddf5ff2e03011dc40c46f7432dcbf937"}},{"ruleId":"D1","level":"warning","message":{"text":"RoutesGenerator.GetPageProperties (cyclomatic 19): RoutesGenerator.GetPageProperties has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd572910cfc464504af488ebfd8940d6485b07d8a6463696d292102060564045"}},{"ruleId":"D1","level":"warning","message":{"text":"RoutesGenerator.EmitFactoryBody (cyclomatic 19): RoutesGenerator.EmitFactoryBody has cyclomatic complexity 19 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":1071}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a9c89a2d11681cde8258183adae39f0f062909b8cdba29a760e6a1420efa2e1"}},{"ruleId":"D1","level":"warning","message":{"text":"UiMenuSurface.OnKeyAsync (cyclomatic 19): UiMenuSurface.OnKeyAsync has cyclomatic complexity 19 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function, or replace a long branch ladder over a single value with a data-driven lookup or dispatch table."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiMenuSurface.cs"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bb61f4041ef00abac793b802cb9c575000a14a0360a69c046549678faf1198c"}},{"ruleId":"D1","level":"warning","message":{"text":"PrerenderShell.StripComments (cyclomatic 19): PrerenderShell.StripComments has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/PrerenderShell.cs"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d489fd359df470e5e78e9cf9a0541c75d44bde44d8cda429d14da6ccde7e0da"}},{"ruleId":"D1","level":"warning","message":{"text":"rask.onFrame (cyclomatic 19): rask.onFrame has cyclomatic complexity 19 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9ef21f11a2afde4f5bfc2caf161d0ee226ca236d63d73816ee41b1c0a63053e"}},{"ruleId":"D1","level":"warning","message":{"text":"CqrsCodecGenerator.Build (cyclomatic 18): CqrsCodecGenerator.Build has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsCodecGenerator.cs"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd874c0a9140f4a5014fc425d797ad0476af4a125c17391805ee0f4810dddb28"}},{"ruleId":"D1","level":"warning","message":{"text":"SvgElement.WriteAttributes (cyclomatic 18): SvgElement.WriteAttributes has cyclomatic complexity 18 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/SvgElement.cs"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"4370c884bc56c82fa00a8136cbb37f03779174d4b03ad3458320e53049791441"}},{"ruleId":"D1","level":"warning","message":{"text":"ExpressionAccessor.TryEvaluate (cyclomatic 18): ExpressionAccessor.TryEvaluate has cyclomatic complexity 18 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/ExpressionAccessor.cs"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"0de90401f8e036fbac212e0b9289ea47717b555fbabbfab4d15090cbc644dd13"}},{"ruleId":"D1","level":"warning","message":{"text":"FormData.FromJson (cyclomatic 18): FormData.FromJson has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FormData.cs"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4468d7196ffba3593bdbcf5c579848c1312f104b7d76bdb46c2af8fffbc9724"}},{"ruleId":"D1","level":"warning","message":{"text":"RaskCqrsEndpointExtensions.HandleAsync (cyclomatic 18): RaskCqrsEndpointExtensions.HandleAsync has cyclomatic complexity 18 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cqrs.Server/RaskCqrsEndpointExtensions.cs"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"531ab16ff3044ff4dc5b26b1206125e2332ce1b027f7b9cb0ea4602a802c4f8e"}},{"ruleId":"D1","level":"warning","message":{"text":"DevToolsPageErrorReceiver.Record (cyclomatic 18): DevToolsPageErrorReceiver.Record has cyclomatic complexity 18 (threshold 15). To reduce it, separate the branches: extract each independent case into its own named function, or replace a long branch ladder over a single value with a data-driven lookup or dispatch table."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Panel/DevToolsPageErrorReceiver.cs"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"bca48983acee7ab8a69b90c1d91c71b234a2242964a6535ec6f74dfc9012808e"}},{"ruleId":"D1","level":"warning","message":{"text":"DevToolsTreeSnapshotter.BadgeOf (cyclomatic 18): DevToolsTreeSnapshotter.BadgeOf has cyclomatic complexity 18 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Probe/DevToolsComponentNode.cs"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"66b72ace7e7f05dcf6d26ef72b74e34205062fc112f96ebd72a2497008711c6b"}},{"ruleId":"D1","level":"warning","message":{"text":"ComponentFactoryGenerator.GetCandidate (cyclomatic 18): ComponentFactoryGenerator.GetCandidate has cyclomatic complexity 18 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":4493}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb2f0bf91f629998215e3381f0af9ba58522bf87a46716fb0119d95b3c6e6491"}},{"ruleId":"D1","level":"warning","message":{"text":"ExternalGenerator.Execute (cyclomatic 18): ExternalGenerator.Execute has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8ae5b30ce70139ac6fad3f083c83f91b1745b4e09edae52645280987d6abe7f"}},{"ruleId":"D1","level":"warning","message":{"text":"PropsSnapshotReader.Read (cyclomatic 18): PropsSnapshotReader.Read has cyclomatic complexity 18 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PropsSnapshotReader.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"340e87760e2c707e3fece2fc600a29bc2094ef59e0ac5638ff78f2a69e8878fc"}},{"ruleId":"D1","level":"warning","message":{"text":"RoutesGenerator.EmitRouteFactory (cyclomatic 18): RoutesGenerator.EmitRouteFactory has cyclomatic complexity 18 (threshold 15). Of this number, 17 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":923}}}],"partialFingerprints":{"codehealthFindingId/v1":"52c730e1c5060abfa3bcd17c40ad916b0a2b4d4181c66e164c4b2f7a83a18bcc"}},{"ruleId":"D1","level":"warning","message":{"text":"SafeFileName.Clean (cyclomatic 18): SafeFileName.Clean has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Upload/SafeFileName.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1cf4116a3adc3368578c11adb9fa023dd08c3e9fec92d6d48238382e3024de3"}},{"ruleId":"D1","level":"warning","message":{"text":"RaskApp.Build (cyclomatic 18): RaskApp.Build has cyclomatic complexity 18 (threshold 15). Of this number, 17 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskApp.cs"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"77c2d61fe8e4a6ecaecc997605764cf3870642115d0a5415b08f458b039dda9f"}},{"ruleId":"D1","level":"warning","message":{"text":"speechRecognition.start (cyclomatic 18): speechRecognition.start has cyclomatic complexity 18 (threshold 15). Of this number, 10 points are the body\u0027s own statements and 8 belong to 4 function literals inside it that branch. To reduce it, separate the branches: extract each independent case into its own named function so the top-level body reads as a short sequence of named decisions."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/speechRecognition.ts"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d014d7b64156fb89dd56d499d2edf5896dad05c03863b6a69a5e1ddeab47db2"}},{"ruleId":"D1","level":"warning","message":{"text":"bridge.createBridge (cyclomatic 18): bridge.createBridge has cyclomatic complexity 18 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/bridge.ts"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"e14c746611b80162b37ed68c1e7f203d4bedc218b8afbe6a741846388a62fa0b"}},{"ruleId":"D1","level":"warning","message":{"text":"TypeWalker.serializeUnion (cyclomatic 18): TypeWalker.serializeUnion has cyclomatic complexity 18 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 3 belong to 2 function literals inside it that branch. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":601}}}],"partialFingerprints":{"codehealthFindingId/v1":"723ed141a8821ba5681539f99d8f36d3bad53b1230b1ca96f114b5623fc6e36d"}},{"ruleId":"D1","level":"warning","message":{"text":"WireShape.ClassifyObject (cyclomatic 17): WireShape.ClassifyObject has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/WireShape.cs"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d6679e4d4b64bba8138b5cbb7c02424170a3fd960e99307d347eff80175457a"}},{"ruleId":"D1","level":"warning","message":{"text":"GeneratedModelShape.EntitiesFor (cyclomatic 17): GeneratedModelShape.EntitiesFor has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/GeneratedModelShape.cs"},"region":{"startLine":361}}}],"partialFingerprints":{"codehealthFindingId/v1":"42d37dc6b44473a7cfb641a8a4297d8c2cab85dd7f78a16ed610a0df5dae89a4"}},{"ruleId":"D1","level":"warning","message":{"text":"TemplateMarkers.Apply (cyclomatic 17): TemplateMarkers.Apply has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Scaffolding/TemplateMarkers.cs"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"08f2726b3b61550a56fb0029907cc136fd7c58b3dfadc6ada941e5b7a86300d0"}},{"ruleId":"D1","level":"warning","message":{"text":"Select.WriteAttributes (cyclomatic 17): Select.WriteAttributes has cyclomatic complexity 17 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Select.cs"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"02e9f49220eeb2fb6e6fc4936d204d98e09094d5b3635f71a09f207f14986134"}},{"ruleId":"D1","level":"warning","message":{"text":"ModelGraphWalker.StepInto (cyclomatic 17): ModelGraphWalker.StepInto has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/ModelGraphWalker.cs"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ccbc7830cc548ee3d7aaec3ac8bc7ac07a291849b7317dd7a4a5047a05e3e93"}},{"ruleId":"D1","level":"warning","message":{"text":"MissingKeyAnalyzer.Analyze (cyclomatic 17): MissingKeyAnalyzer.Analyze has cyclomatic complexity 17 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa58c302e48cc0d74d7ddf93c00382c02ca6ec125a43f7705a2cece5e646d040"}},{"ruleId":"D1","level":"warning","message":{"text":"JsonScanner.TryReadString (cyclomatic 17): JsonScanner.TryReadString has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Json/JsonScanner.cs"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bc7fca78208573a785cf8d84691b008310047b3aba0c01fd44e817a680ae88f"}},{"ruleId":"D1","level":"warning","message":{"text":"RoutesGenerator.GetCandidate (cyclomatic 17): RoutesGenerator.GetCandidate has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"901ed346a2b2b2e3cf1af79145625d31f884c1bf6af4aa6941eb07bb6717fc68"}},{"ruleId":"D1","level":"warning","message":{"text":"RoutesGenerator.GetOrphanCandidate (cyclomatic 17): RoutesGenerator.GetOrphanCandidate has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":499}}}],"partialFingerprints":{"codehealthFindingId/v1":"96a65fd1019beff58fd719fd6384f91b931d05d4f47a6e279fba9292f0042cdf"}},{"ruleId":"D1","level":"warning","message":{"text":"rask-morph.raskNotePendingFormState (cyclomatic 17): rask-morph.raskNotePendingFormState has cyclomatic complexity 17 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"2af3bed150a1ce64e89e19d88c7f38e1ff0b82233569d725b7df84cd1f019333"}},{"ruleId":"D1","level":"warning","message":{"text":"flash.changedElements (cyclomatic 17): flash.changedElements has cyclomatic complexity 17 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/flash.ts"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e20b356b4de25bf14fd3f441d3ca04ab1bff09b122caedca74d79b3de75bed1"}},{"ruleId":"D1","level":"warning","message":{"text":"flash.installFlash (cyclomatic 17): flash.installFlash has cyclomatic complexity 17 (threshold 15). Of this number, 9 points are the body\u0027s own statements and 8 belong to 3 function literals inside it that branch. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/flash.ts"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"713c0483d747ba952dedf965a0851954222a5be0ed2d41eb6aa26d3e5de19b16"}},{"ruleId":"D1","level":"warning","message":{"text":"PasskeyVerifier.IsExpectedClientData (cyclomatic 16): PasskeyVerifier.IsExpectedClientData has cyclomatic complexity 16 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Auth.Api/PasskeyVerifier.cs"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0ae6942d632a6b7c1e8cf1272d4c60ce5761ce8c56b8cad75fd087abadaabbc"}},{"ruleId":"D1","level":"warning","message":{"text":"DevCommand.ExecuteAsync (cyclomatic 16): DevCommand.ExecuteAsync has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DevCommand.cs"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa86b36371ca65572b8942907d8ea7eaad11550172a422172c02c3b58523a658"}},{"ruleId":"D1","level":"warning","message":{"text":"Button.WriteAttributes (cyclomatic 16): Button.WriteAttributes has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Button.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"c33d6d82472386dd87a4ff519edebdd28fcb657f04c44533b8cc77b027ef2a91"}},{"ruleId":"D1","level":"warning","message":{"text":"Link.WriteAttributes (cyclomatic 16): Link.WriteAttributes has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Link.cs"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb257e48c42f30bd13d706131e05aa7593f4b0562eb9647e00df4504c13aef12"}},{"ruleId":"D1","level":"warning","message":{"text":"RequiredBuilderPropertyAnalyzer.Analyze (cyclomatic 16): RequiredBuilderPropertyAnalyzer.Analyze has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/RequiredBuilderPropertyAnalyzer.cs"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"d63387ec2a31161e9cf39bd91f34d5f3b0dd709fbb7bc5a292ba3f9a1a62c06e"}},{"ruleId":"D1","level":"warning","message":{"text":"ExternalGenerator.Describe (cyclomatic 16): ExternalGenerator.Describe has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c6d4733567fdc76e6d55527f024c005295f4dc61c16a8d0c7b6a84c709cbdbb"}},{"ruleId":"D1","level":"warning","message":{"text":"rask.trackHeadAsset (cyclomatic 16): rask.trackHeadAsset has cyclomatic complexity 16 (threshold 15). Of this number, 12 points are the body\u0027s own statements and 4 belong to one function literal inside it that branches. To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1346}}}],"partialFingerprints":{"codehealthFindingId/v1":"95b88cb826e3e0403587a56dbc9a078e923453bc6c28088fafd382883d9b3291"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-morph.morph (cognitive 136): rask-morph.morph has cognitive complexity 136 (threshold 15). Drivers by points: if/else 42 (84 pts), boolean chains 22, loops 11 (16 pts), ternaries 5 (14 pts) (nesting depth added 56). Of this number, 131 points are the body\u0027s own statements and 5 belong to 2 function literals inside it that branch. To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb82a3b439e14c90cef25d175844d62a71fdd4f8c00ce6208907622e3d92cab7"}},{"ruleId":"D2","level":"warning","message":{"text":"HtmlSerializer.Serialize (cognitive 95): HtmlSerializer.Serialize has cognitive complexity 95 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/HtmlSerializer.cs"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4345025212bc9ce9231aa770b652becb998d7b8c3cd8322dba4037d8822d5c8"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskEndpointExtensions.RunSocketLoop (cognitive 79): RaskEndpointExtensions.RunSocketLoop has cognitive complexity 79 (threshold 15). Of this number, 78 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1357}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef189758f3488463510dd381080dc91297bfb8f31a5711d243943bfe3a1d50c4"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelInputGenerator.Render (cognitive 75): ModelInputGenerator.Render has cognitive complexity 75 (threshold 15). Of this number, 74 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":686}}}],"partialFingerprints":{"codehealthFindingId/v1":"8387f70b7fe05e4ee988f379a6a7b7aa08f62968b8852d9adcc616778dcbe7a7"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.GetFactoryProperties (cognitive 66): ComponentFactoryGenerator.GetFactoryProperties has cognitive complexity 66 (threshold 15). Of this number, 64 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":5119}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fcf3a0a2b9956e7566447935731927e02bbe053d09a78e8efe697cf7f10d3be"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-dom.applyDiff (cognitive 66): rask-dom.applyDiff has cognitive complexity 66 (threshold 15). Drivers by points: if/else 13 (39 pts), loops 5 (13 pts), ternaries 2 (7 pts), boolean chains 5, match/switch 1 (2 pts) (nesting depth added 40). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"57ad0b950a920cefa2aa2eb103a7a6e045e4433ec7d38fc6c17dd5ddf6f4870f"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalGenerator.Emit (cognitive 65): ExternalGenerator.Emit has cognitive complexity 65 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":792}}}],"partialFingerprints":{"codehealthFindingId/v1":"520ae0c5d34152203a3a0459470b3f39cdcb92ae2c64b7f2ae1c0cba0ceadeeb"}},{"ruleId":"D2","level":"warning","message":{"text":"Input.WriteAttributes (cognitive 62): Input.WriteAttributes has cognitive complexity 62 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Input.cs"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"31af2184f21332c781441b3aeb81bab0f89cbdf042be65d982b547ca9d3923a0"}},{"ruleId":"D2","level":"warning","message":{"text":"FrameDiffer.DiffKeyedSiblings (cognitive 59): FrameDiffer.DiffKeyedSiblings has cognitive complexity 59 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":814}}}],"partialFingerprints":{"codehealthFindingId/v1":"b901c28ca91c876da598adcb37c5d3e79f96f851a1d43dd86561e8bb7ac175c3"}},{"ruleId":"D2","level":"warning","message":{"text":"MessageParser.Parse (cognitive 58): MessageParser.Parse has cognitive complexity 58 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/MessageParser.cs"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2125f415e6b19442ec2c8f7700bbc31e9904abed1696b6ea40a3f71e289f6d0"}},{"ruleId":"D2","level":"warning","message":{"text":"EditContext.ValidateFieldAsync (cognitive 57): EditContext.ValidateFieldAsync has cognitive complexity 57 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/EditContext.cs"},"region":{"startLine":716}}}],"partialFingerprints":{"codehealthFindingId/v1":"32a56f87bb1e452b4f19de0cc9ba7f55ddd322f0ca667423e5d4d8e9ea8494a6"}},{"ruleId":"D2","level":"warning","message":{"text":"LivePayload.BuildPayloadUtf8Diff (cognitive 55): LivePayload.BuildPayloadUtf8Diff has cognitive complexity 55 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"45692061ab13dc925f35ecce3a98782c0a413da4c4bbd915b76ce9a6bd7ed3ea"}},{"ruleId":"D2","level":"warning","message":{"text":"affected_projects.main (cognitive 55): affected_projects.main has cognitive complexity 55 (threshold 15). Drivers by points: if/else 12 (27 pts), loops 11 (16 pts), error handling 3 (8 pts), boolean chains 3, ternaries 1 (nesting depth added 25). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/lib/affected_projects.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"46704b4eefd9dc473a57d9a912340701dbc8ea005cac602a19614e7bc58fc966"}},{"ruleId":"D2","level":"warning","message":{"text":"TranslationCatalogGenerator.EmitFamily (cognitive 54): TranslationCatalogGenerator.EmitFamily has cognitive complexity 54 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/TranslationCatalogGenerator.cs"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce4958d0630b9beb18d5a9be175aeaf7acfcb0afed7ab42a9892e143341041f1"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalPackageScan.Blank (cognitive 52): ExternalPackageScan.Blank has cognitive complexity 52 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageScan.cs"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"09269064b686db1e0396384dbf15be25042bad6bb4ee489565b2845191328858"}},{"ruleId":"D2","level":"warning","message":{"text":"panel-client.installPanelClient (cognitive 49): panel-client.installPanelClient has cognitive complexity 49 (threshold 15). Drivers by points: if/else 29 (33 pts), ternaries 7 (8 pts), boolean chains 6, loops 2 (nesting depth added 5). Most of this is not in the body itself: 1 of the 49 points is its own statement and the rest belongs to 10 function literals inside it that branch (lines 147, 201, 66, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/panel/panel-client.ts"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"17bd41cae5b408782fa35d295351b1f6f8676216038a34c3bc8d56c207689f79"}},{"ruleId":"D2","level":"warning","message":{"text":"DeployCommand.ExecuteAsync (cognitive 47): DeployCommand.ExecuteAsync has cognitive complexity 47 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DeployCommand.cs"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec96df5904a7f2b58e192030fea1e31ddb7412e5d3ddf488d380acca455b1b10"}},{"ruleId":"D2","level":"warning","message":{"text":"ContentSniffer.Signature (cognitive 47): ContentSniffer.Signature has cognitive complexity 47 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Upload/ContentSniffer.cs"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c6ab5bc54766bcb2d06d7234494a5535bad278df9a256465a9ab2121c8557a3"}},{"ruleId":"D2","level":"warning","message":{"text":"extract-props.extractIsland (cognitive 47): extract-props.extractIsland has cognitive complexity 47 (threshold 15). Drivers by points: ternaries 8 (20 pts), if/else 11 (18 pts), boolean chains 5, error handling 1 (2 pts), loops 2 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"f069002ed33675c5d9679e170312411d5bc610fb4e6b51828b2d7207f6dcc7ec"}},{"ruleId":"D2","level":"warning","message":{"text":"ArgumentSchema.Parse (cognitive 45): ArgumentSchema.Parse has cognitive complexity 45 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/ArgumentSchema.cs"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"48b685be664484d4bed37b392e028e042659e23fd057e93ad68fd2453067b68d"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-http-transport.openHttpConnection (cognitive 44): rask-http-transport.openHttpConnection has cognitive complexity 44 (threshold 15). Drivers by points: if/else 15 (24 pts), boolean chains 6, ternaries 3 (6 pts), error handling 3 (4 pts), loops 2 (4 pts) (nesting depth added 15). Most of this is not in the body itself: 11 of the 44 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 356, 396, 353). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask-http-transport.ts"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"baa23249115e92267ca97fa6cf56f1ed52c99d682d89994edeb1efa1ce57b9c5"}},{"ruleId":"D2","level":"warning","message":{"text":"DbCommand.ExecuteAsync (cognitive 43): DbCommand.ExecuteAsync has cognitive complexity 43 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DbCommand.cs"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"b630bcf9f809d7fa41c4a7dcd1aec3c0604b469fc6ead356ca6503fd7bdbf91c"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.EmitConsumerEntries (cognitive 43): ComponentFactoryGenerator.EmitConsumerEntries has cognitive complexity 43 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":3417}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d206ff13b55cb7f9c484cddd02101bc45748a60badfabf4db056629254e9f06"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.Emit (cognitive 43): RoutesGenerator.Emit has cognitive complexity 43 (threshold 15). Of this number, 42 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":649}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2b6fdd7cbb6d525c2a6cd31fda3d654b12b98379be88cd394675fb484c588a8"}},{"ruleId":"D2","level":"warning","message":{"text":"extract-props.extractAngular (cognitive 42): extract-props.extractAngular has cognitive complexity 42 (threshold 15). Drivers by points: ternaries 11 (24 pts), if/else 6 (9 pts), boolean chains 5, error handling 1 (2 pts), loops 2 (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":1188}}}],"partialFingerprints":{"codehealthFindingId/v1":"f522a6934513d31a73b1976fe31e20c46c1fbee3a0f838bd45b53166ba6e2bf8"}},{"ruleId":"D2","level":"warning","message":{"text":"NewCommand.GenerateDirectAsync (cognitive 41): NewCommand.GenerateDirectAsync has cognitive complexity 41 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":681}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c29896b908847b1835fa9131c0ed1d21a0caeaf73408a1633a3ca6da498345b"}},{"ruleId":"D2","level":"warning","message":{"text":"client.httpTransport (cognitive 41): client.httpTransport has cognitive complexity 41 (threshold 15). Drivers by points: if/else 16 (22 pts), ternaries 5 (8 pts), boolean chains 6, loops 3 (4 pts), error handling 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/client/client.ts"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"12cef9b4fa75eb636e1b67bf0797f33daeaf7676ed169dc0bcd00f87080dc7fc"}},{"ruleId":"D2","level":"warning","message":{"text":"BakeScopedAssetsTask.BakeFromAssemblies (cognitive 40): BakeScopedAssetsTask.BakeFromAssemblies has cognitive complexity 40 (threshold 15). Of this number, 33 points are the body\u0027s own statements and 7 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"97e5b4617bead21c334c08f1068928fde765fa70b436548bccc8624988c0ff03"}},{"ruleId":"D2","level":"warning","message":{"text":"CssScoper.RewriteBlock (cognitive 38): CssScoper.RewriteBlock has cognitive complexity 38 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedCss/CssScoper.cs"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fb3affe2c5bd20b847dcb50fc2535f9f905c7edb6c4a61b986eee72ace1a350"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.EmitFactoryBody (cognitive 37): RoutesGenerator.EmitFactoryBody has cognitive complexity 37 (threshold 15). Of this number, 36 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":1071}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd53ab2b63b58ae2a6cf317923544db2e96480098972d2aa2f02bb1af28c66d5"}},{"ruleId":"D2","level":"warning","message":{"text":"WasmPrerender.PatchManifest (cognitive 37): WasmPrerender.PatchManifest has cognitive complexity 37 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/WasmPrerender.cs"},"region":{"startLine":414}}}],"partialFingerprints":{"codehealthFindingId/v1":"963567673df2c0b7ca19c8493613844463cc75709b11abdb2260fe804c4f924f"}},{"ruleId":"D2","level":"warning","message":{"text":"TypeWalker.serialize (cognitive 37): TypeWalker.serialize has cognitive complexity 37 (threshold 15). Drivers by points: if/else 22 (25 pts), boolean chains 8, ternaries 2 (4 pts) (nesting depth added 5). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":499}}}],"partialFingerprints":{"codehealthFindingId/v1":"8061998d1959719176692fdc7749d1fdb266a32d8c3a07a690da34d5fb89a4cc"}},{"ruleId":"D2","level":"warning","message":{"text":"CssMinifier.Minify (cognitive 36): CssMinifier.Minify has cognitive complexity 36 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedAssets/CssMinifier.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e0e69e8ff8bc6c01738a6a4d583ba675c5841c691b113b35d6dc0941c0921dc"}},{"ruleId":"D2","level":"warning","message":{"text":"angular.renderChildren (cognitive 34): angular.renderChildren has cognitive complexity 34 (threshold 15). Drivers by points: if/else 12 (22 pts), boolean chains 4, loops 4, ternaries 2 (4 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/angular.ts"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9de11e3d4c1cec53093b64febdd8b22cdb8f6d63e423c84f57d020b021b519e"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalPackageScan.FindOverride (cognitive 33): ExternalPackageScan.FindOverride has cognitive complexity 33 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageScan.cs"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"12c9ea5feb61797dac11e692e8049efcacb8e4e67f85ef8b1fb514bceb0c663a"}},{"ruleId":"D2","level":"warning","message":{"text":"BlazorParameters.Read (cognitive 33): BlazorParameters.Read has cognitive complexity 33 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Blazor/BlazorParameters.cs"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"437a02d2447a9da5b15231f6392d520295e2b7d0a1c14d5cebffa79bd726ad85"}},{"ruleId":"D2","level":"warning","message":{"text":"extract-props.extractLit (cognitive 33): extract-props.extractLit has cognitive complexity 33 (threshold 15). Drivers by points: if/else 10 (14 pts), ternaries 4 (9 pts), boolean chains 6, error handling 1 (2 pts), loops 2 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":941}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3a0f726c864dcbbc0cafa333f150055a1d9d9dead38034ce8f43384518b44d4"}},{"ruleId":"D2","level":"warning","message":{"text":"Component.RenderForLive (cognitive 32): Component.RenderForLive has cognitive complexity 32 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":1253}}}],"partialFingerprints":{"codehealthFindingId/v1":"12a003b15f3707dfac4c9365895353dda3ac2bcd1b7776570a679e8eb0b478ab"}},{"ruleId":"D2","level":"warning","message":{"text":"FormData.FromJson (cognitive 32): FormData.FromJson has cognitive complexity 32 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FormData.cs"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"abe7eae2efab8cb0999a25ff2ebecf0005bedce436368377baa4b4aa56774fd6"}},{"ruleId":"D2","level":"warning","message":{"text":"CssScoper.AppendScopedSelector (cognitive 32): CssScoper.AppendScopedSelector has cognitive complexity 32 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedCss/CssScoper.cs"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"52f6e912798ea7edac5f9fc7faedfd1731c86623fb3b836bf8a9870648059499"}},{"ruleId":"D2","level":"warning","message":{"text":"WriteExternalBuildInputsTask.Execute (cognitive 32): WriteExternalBuildInputsTask.Execute has cognitive complexity 32 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/WriteExternalBuildInputsTask.cs"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"8788d3773626637eadb98b6be8a84481a2c517ab480e61e04a69fea270d7bd1b"}},{"ruleId":"D2","level":"warning","message":{"text":"lit.renderChildren (cognitive 32): lit.renderChildren has cognitive complexity 32 (threshold 15). Drivers by points: if/else 11 (22 pts), boolean chains 4, loops 4, ternaries 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/lit.ts"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"dab8fab5730298a6085e43fb39b72da6d3f85640151f0a8eaff8da3cfed34abe"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalGenerator.Execute (cognitive 31): ExternalGenerator.Execute has cognitive complexity 31 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e58ccce3462d0f145cd573c20168b382be07410c45222baa6cb544463fb99b1"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.GetPageProperties (cognitive 31): RoutesGenerator.GetPageProperties has cognitive complexity 31 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6a2edc50a032fe656fe5170f9ba30da7d732a4a039892f9e47f9c025434b63c"}},{"ruleId":"D2","level":"warning","message":{"text":"HtmlTree.TryReadStartTag (cognitive 31): HtmlTree.TryReadStartTag has cognitive complexity 31 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Testing/HtmlTree.cs"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"55f0e477b6e3db98264874d36673ae310c5fe0ea9866707efaf89a376f76ce80"}},{"ruleId":"D2","level":"warning","message":{"text":"TemplateMarkers.Apply (cognitive 30): TemplateMarkers.Apply has cognitive complexity 30 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Scaffolding/TemplateMarkers.cs"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"69ff1c187f61554c011bdf8c68f73c8d087fb3cf0cd3a47a64e0e3cfa03c0fc1"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.EmitRouteFactory (cognitive 30): RoutesGenerator.EmitRouteFactory has cognitive complexity 30 (threshold 15). Of this number, 29 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":923}}}],"partialFingerprints":{"codehealthFindingId/v1":"715a24212dfeb5bc1c0dcc1bf09165ff820a574b20bf03fc70c6815f50af0143"}},{"ruleId":"D2","level":"warning","message":{"text":"PrerenderShell.StripComments (cognitive 30): PrerenderShell.StripComments has cognitive complexity 30 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/PrerenderShell.cs"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f41927462c0502ead1d8bb6db87d40d2c45e45b735e2986305d61eb3c1bf23c"}},{"ruleId":"D2","level":"warning","message":{"text":"rask.applyFullReply (cognitive 30): rask.applyFullReply has cognitive complexity 30 (threshold 15). Drivers by points: if/else 15 (21 pts), boolean chains 7, ternaries 1 (2 pts) (nesting depth added 7). Most of this is not in the body itself: 4 of the 30 points are its own statements and the rest belongs to one function literal inside it that branches (line 1496). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1489}}}],"partialFingerprints":{"codehealthFindingId/v1":"55cb1fce91b8c9e35610160c6afe99b4d2069d9f554c01977cc0902849ccf52a"}},{"ruleId":"D2","level":"warning","message":{"text":"SymbolRegistration.DescribeUnnameableWithRemedy (cognitive 28): SymbolRegistration.DescribeUnnameableWithRemedy has cognitive complexity 28 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/SymbolRegistration.cs"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f29a1c0cc9a57d08e1506d7453be8c13adb609e7d9d2aee2db7a46482fe47c0"}},{"ruleId":"D2","level":"warning","message":{"text":"NewCommand.ExecuteAsync (cognitive 28): NewCommand.ExecuteAsync has cognitive complexity 28 (threshold 15). Of this number, 26 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"567a84c926f8b54057119ebcf8979378c1d3e0ce0886a402d8e9e92ba7c1dbbb"}},{"ruleId":"D2","level":"warning","message":{"text":"Element.AppendPrefixedAttrs (cognitive 28): Element.AppendPrefixedAttrs has cognitive complexity 28 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Element.cs"},"region":{"startLine":510}}}],"partialFingerprints":{"codehealthFindingId/v1":"fed4abf7b76b78c156f3126a5959d97f948dbb207d6fdcb50e5ed27a7067d084"}},{"ruleId":"D2","level":"warning","message":{"text":"FrameDiffer.DiffSiblings (cognitive 28): FrameDiffer.DiffSiblings has cognitive complexity 28 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"c14101dc020a920e88d3aa41d2eaf514e1105d45ab3ae0f63aacc55ffd7c2c6f"}},{"ruleId":"D2","level":"warning","message":{"text":"PropsSnapshotReader.ReadType (cognitive 28): PropsSnapshotReader.ReadType has cognitive complexity 28 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PropsSnapshotReader.cs"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"8296eaaa3c6268bc75c71e3f6d44e2b48e7f97713fbbb2235f564e022f226fab"}},{"ruleId":"D2","level":"warning","message":{"text":"HtmlTree.Parse (cognitive 28): HtmlTree.Parse has cognitive complexity 28 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Testing/HtmlTree.cs"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2b6ee73aff0aa33e5f3147f42517aedbc7714f2a6266bf9561e37c0c550dd42"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskBatteryWiring.Apply (cognitive 28): RaskBatteryWiring.Apply has cognitive complexity 28 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskBatteryWiring.cs"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c040a9d59f26350430bc01fcd43e4459b56a76d61d10680a0c5e57c5618f719"}},{"ruleId":"D2","level":"warning","message":{"text":"Element.WriteAttributes (cognitive 27): Element.WriteAttributes has cognitive complexity 27 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Element.cs"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"067c04a71af67af09e5c27fa34e0a54a10c19dda6df57499d8cdc888b34f24f7"}},{"ruleId":"D2","level":"warning","message":{"text":"LiveSessionBase.WritePayload (cognitive 27): LiveSessionBase.WritePayload has cognitive complexity 27 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LiveSessionBase.cs"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fee15a124e54df16609287ab986ea7e9c81a86f25be273d68d8962a812efde7"}},{"ruleId":"D2","level":"warning","message":{"text":"UiSelect.OnKeyAsync (cognitive 27): UiSelect.OnKeyAsync has cognitive complexity 27 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiSelect.cs"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7821e32003c02b177cfc3239bd8c5fe899b78baff643a3f726f80fa80d0c309"}},{"ruleId":"D2","level":"warning","message":{"text":"HostSetup.EnsureReadyAsync (cognitive 26): HostSetup.EnsureReadyAsync has cognitive complexity 26 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/HostSetup.cs"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"986cdf9fa6fc5a3f5fc450f041df30c5e0c79628f5a2f67befc3b7a4681cc3a0"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelBuilderExtensions.Apply (cognitive 26): ModelBuilderExtensions.Apply has cognitive complexity 26 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/ModelBuilderExtensions.cs"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"53215ef65a7bd86fc59a3c99956e58a83c0dc074a903c2e63dd26dec5620b699"}},{"ruleId":"D2","level":"warning","message":{"text":"ReadModelRegistry.MapColumns (cognitive 26): ReadModelRegistry.MapColumns has cognitive complexity 26 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/ReadModelRegistry.cs"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dd97d9eb198fae079bc44ff448f7c91e2f98f1df9bf15191d792bfce0547430"}},{"ruleId":"D2","level":"warning","message":{"text":"flash.changedElements (cognitive 26): flash.changedElements has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 5, ternaries 1 (2 pts), loops 1 (nesting depth added 11). Of this number, 20 points are the body\u0027s own statements and 6 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/flash.ts"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dfd1fd1f43744d730c96f1a5c82e5c8e955fa4a25667f662142d0ecf19330da"}},{"ruleId":"D2","level":"warning","message":{"text":"CqrsCodecGenerator.Build (cognitive 25): CqrsCodecGenerator.Build has cognitive complexity 25 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsCodecGenerator.cs"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b8936d80cc47db629d98d39ac75b4c49f89c412610982af9bd5694b6b030f87"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelInputGenerator.Emit (cognitive 25): ModelInputGenerator.Emit has cognitive complexity 25 (threshold 15). Of this number, 24 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":595}}}],"partialFingerprints":{"codehealthFindingId/v1":"8086e8914649a5bafe575b9f20137115a8f2b93078be6ec879275ea09aa05853"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalPackageScan.ReadLiteral (cognitive 25): ExternalPackageScan.ReadLiteral has cognitive complexity 25 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageScan.cs"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e6781d901904c51473fd274420f9895c5d1b74a33e13e76b6429fbe454f5839"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.TryParseTemplate (cognitive 25): RoutesGenerator.TryParseTemplate has cognitive complexity 25 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":1460}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c302d3ef66e32897a0c9120d78190aefa4906e36b415e4887d1678fe29552cb"}},{"ruleId":"D2","level":"warning","message":{"text":"JobProcessor.DrainAsync (cognitive 25): JobProcessor.DrainAsync has cognitive complexity 25 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobProcessor.cs"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"1069798d775e4acc7bfc7327bcb6499d31213877d7cda35382037676caca0322"}},{"ruleId":"D2","level":"warning","message":{"text":"OutboxProcessor.DrainAsync (cognitive 25): OutboxProcessor.DrainAsync has cognitive complexity 25 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Outbox/OutboxProcessor.cs"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c761ddc56a3298958930808b04ce52601a29a75a3175ddf2f20d89a089f236f"}},{"ruleId":"D2","level":"warning","message":{"text":"AzureAccount.Parse (cognitive 25): AzureAccount.Parse has cognitive complexity 25 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Backends/AzureAccount.cs"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ff0429a980b1ec0c6a4de3b100fd9e6946c504cbd95b31f48fce31a541a17c8"}},{"ruleId":"D2","level":"warning","message":{"text":"WireShape.Classify (cognitive 24): WireShape.Classify has cognitive complexity 24 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/WireShape.cs"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4e92451725b1960e2147530b8232463702b88e44229318eab6af12257e3d24f"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelRegistryGenerator.EmitDbSets (cognitive 24): ModelRegistryGenerator.EmitDbSets has cognitive complexity 24 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelRegistryGenerator.cs"},"region":{"startLine":373}}}],"partialFingerprints":{"codehealthFindingId/v1":"4216479d772e9701d288508de5af240161865d165de4a5e7866968111db27d22"}},{"ruleId":"D2","level":"warning","message":{"text":"FramePathWalker.TryResolve (cognitive 24): FramePathWalker.TryResolve has cognitive complexity 24 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FramePathWalker.cs"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"813329b902cea8fe43e5da70246a72615f02d4c1133ce21010f35b546cab508e"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalSourceScan.IslandRuntimes (cognitive 24): ExternalSourceScan.IslandRuntimes has cognitive complexity 24 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalSourceScan.cs"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e43e9cd38edbe0dd74d45927e9824c918ed2e5b0ae873254ca69a8b9f382693"}},{"ruleId":"D2","level":"warning","message":{"text":"PackageIslandEmitter.Types (cognitive 23): PackageIslandEmitter.Types has cognitive complexity 23 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PackageIslandEmitter.cs"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"c46b52f1ff71dd8647590ca492046f061711feec46d6fb6f0a30bcefed0f1c74"}},{"ruleId":"D2","level":"warning","message":{"text":"SafeFileName.Clean (cognitive 23): SafeFileName.Clean has cognitive complexity 23 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Upload/SafeFileName.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c8f80e616ebb44c318b0bbd1c34f68155323d588c43f5350ec60d0eeeda55b9"}},{"ruleId":"D2","level":"warning","message":{"text":"bridge.createBridge (cognitive 23): bridge.createBridge has cognitive complexity 23 (threshold 15). Drivers by points: if/else 10 (17 pts), ternaries 1 (3 pts), boolean chains 2, match/switch 1 (nesting depth added 9). Of this number, 22 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/bridge.ts"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"05ce2dc63aae241758ffecb1a85a4ff978e5b85eae3d8c21efcdbd86458ea8aa"}},{"ruleId":"D2","level":"warning","message":{"text":"BulkInsertPlan.Build (cognitive 22): BulkInsertPlan.Build has cognitive complexity 22 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/BulkInsertPlan.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"f805ca4463ea39f3d67c0f31bc1a37dc6a40d1b931fc0b126c669b3d7a5fdd7e"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.EmitBoundEntry (cognitive 22): ComponentFactoryGenerator.EmitBoundEntry has cognitive complexity 22 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":3219}}}],"partialFingerprints":{"codehealthFindingId/v1":"e368e3eae2c015546711ebc8db5f10314813b8a8e1577969a17ac2b41f47829d"}},{"ruleId":"D2","level":"warning","message":{"text":"PropsSnapshotReader.Read (cognitive 22): PropsSnapshotReader.Read has cognitive complexity 22 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PropsSnapshotReader.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"531c9863eacc37d1e0aaba6a25847cc91276bf37f98cf014e10d2b3876f5e6cb"}},{"ruleId":"D2","level":"warning","message":{"text":"rask.onFrame (cognitive 22): rask.onFrame has cognitive complexity 22 (threshold 15). Drivers by points: if/else 14 (17 pts), boolean chains 4, error handling 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"675d5e2370a3ab5071d4b093e22eb0bfade7a3a8423cce1edaf6ae16cf98377a"}},{"ruleId":"D2","level":"warning","message":{"text":"rask.wasm.trackHeadAsset (cognitive 22): rask.wasm.trackHeadAsset has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 10, if/else 9, ternaries 2 (3 pts) (nesting depth added 1). Of this number, 17 points are the body\u0027s own statements and 5 belong to one function literal inside it that branches. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask.wasm.ts"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe0adad32fc70a58cbd1df172f739f62e93333c1f7b577c5174eb0ef8bcfe46e"}},{"ruleId":"D2","level":"warning","message":{"text":"revive (cognitive 22): revive has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 3 (9 pts), if/else 5 (6 pts), boolean chains 4, loops 2 (3 pts) (nesting depth added 8). Of this number, 18 points are the body\u0027s own statements and 4 belong to 4 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/wwwroot/rask-external.js"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"15cf1268cc4c20351bff3226be40005b3d2830d82d6d59c44bc115ff49b12bae"}},{"ruleId":"D2","level":"warning","message":{"text":"CqrsCodecGenerator.DiscoverMessages (cognitive 21): CqrsCodecGenerator.DiscoverMessages has cognitive complexity 21 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsCodecGenerator.cs"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"ead6186f1e4160b76ea538f63a5a33cf01d51821352401a12e553eba3c5e2802"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalBuildPlan.Refuse (cognitive 21): ExternalBuildPlan.Refuse has cognitive complexity 21 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalBuildPlan.cs"},"region":{"startLine":548}}}],"partialFingerprints":{"codehealthFindingId/v1":"8060a278e5ac62791807b28abe648242d229521c4b08fde14b453a1786b26f6d"}},{"ruleId":"D2","level":"warning","message":{"text":"AuthBeforeRaskAnalyzer.Analyze (cognitive 21): AuthBeforeRaskAnalyzer.Analyze has cognitive complexity 21 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/AuthBeforeRaskAnalyzer.cs"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"57d60659f057dfd4353c5512612476dc0fcbae782939f3de2c78f43b2c088b70"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.GetSetterHost (cognitive 21): ComponentFactoryGenerator.GetSetterHost has cognitive complexity 21 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"a587e7a324e1c822f0038242ed3825aaf435f5cfb9f2dd251f25a5e4382ca99c"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentScopedJsGenerator.Emit (cognitive 21): ComponentScopedJsGenerator.Emit has cognitive complexity 21 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedJsGenerator.cs"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"eeed6cbdf34fc7a5f6c5b7caad9e2fabb44cf7d05e716ceac45e10c1ff4ff8b5"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.GetCandidate (cognitive 21): RoutesGenerator.GetCandidate has cognitive complexity 21 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6954d3fd5914bbcbb184cdd66e973f797caf70f1a606cc96041d7ef28535226"}},{"ruleId":"D2","level":"warning","message":{"text":"Reader.ReadObject (cognitive 21): Reader.ReadObject has cognitive complexity 21 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/JsonCatalogReader.cs"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"d732917d9e0939d798478578a21b798af0ef7ea49c451e77d3115bbcae89a330"}},{"ruleId":"D2","level":"warning","message":{"text":"TranslationCatalogGenerator.IsCultureTag (cognitive 21): TranslationCatalogGenerator.IsCultureTag has cognitive complexity 21 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/TranslationCatalogGenerator.cs"},"region":{"startLine":792}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf496a3bd9d7519dc8b1a69d1902c9d82d679c3bfcbb7f1db215e2ba47ed36b"}},{"ruleId":"D2","level":"warning","message":{"text":"UiSelect.Custom (cognitive 21): UiSelect.Custom has cognitive complexity 21 (threshold 15). Of this number, 19 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiSelect.cs"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"df8269d6e3ea6010fb63493b924972f01c56d8530cfd0974100d4223ff6b19b0"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-morph.raskNotePendingFormState (cognitive 21): rask-morph.raskNotePendingFormState has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (6 pts), ternaries 4 (6 pts), loops 2 (5 pts), boolean chains 4 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7f7c6bf731380d5f630724280c4d10b5f967ddf7ae51d8a8ea49f13f3848735"}},{"ruleId":"D2","level":"warning","message":{"text":"overlay.installOverlay (cognitive 21): overlay.installOverlay has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (10 pts), boolean chains 8, ternaries 2, loops 1 (nesting depth added 1). Most of this is not in the body itself: 4 of the 21 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 127, 95, 115, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/overlay.ts"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"75d327e29a3e188acb67ed8f892411404c7a1e5d8e9236ac05032597372a45c0"}},{"ruleId":"D2","level":"warning","message":{"text":"rask.saveRestoreFields (cognitive 21): rask.saveRestoreFields has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 4, ternaries 1 (2 pts), error handling 1, loops 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":778}}}],"partialFingerprints":{"codehealthFindingId/v1":"927f93640e94f8b614f1eb087eb32c90d8fda578e94b612080a492a092c02754"}},{"ruleId":"D2","level":"warning","message":{"text":"WireShape.ClassifyObject (cognitive 20): WireShape.ClassifyObject has cognitive complexity 20 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/WireShape.cs"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"6de86095d95d95fb1e390319292b1303b173ac644608ed3063d75cccc3f81e98"}},{"ruleId":"D2","level":"warning","message":{"text":"ValueObjectCollector.Of (cognitive 20): ValueObjectCollector.Of has cognitive complexity 20 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 5 belong to 4 function literals inside it that branch. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/GeneratedModelShape.cs"},"region":{"startLine":798}}}],"partialFingerprints":{"codehealthFindingId/v1":"6af922b1e3762275a9ad1cfa595d0d779c8b9e9919cfc504f560ed0c7f6648ef"}},{"ruleId":"D2","level":"warning","message":{"text":"CqrsCodecGenerator.DiscoverHandlers (cognitive 20): CqrsCodecGenerator.DiscoverHandlers has cognitive complexity 20 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsCodecGenerator.cs"},"region":{"startLine":252}}}],"partialFingerprints":{"codehealthFindingId/v1":"c59670066bc9f0428751092f8201745bfb21206a44c1ad76a89add0404c0d3ad"}},{"ruleId":"D2","level":"warning","message":{"text":"Textarea.WriteAttributes (cognitive 20): Textarea.WriteAttributes has cognitive complexity 20 (threshold 15). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Textarea.cs"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"031312e1bcb6e6e9fb1174779721e22ac1e24b4bd56ffbd34f187ee892182ce8"}},{"ruleId":"D2","level":"warning","message":{"text":"PositionIndex.RemoveAt (cognitive 20): PositionIndex.RemoveAt has cognitive complexity 20 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/PositionIndex.cs"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"72229b7b00dfa068be11701cafd542b162860f7109df30624e1f4e56bd926e64"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.EmitPropsDescribers (cognitive 20): ComponentFactoryGenerator.EmitPropsDescribers has cognitive complexity 20 (threshold 15). Of this number, 19 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":3699}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e3703e0830363ffbd24fa41f6c12f69ea9ec192289035d4bf25be38cf068578"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.GetForwarderInfos (cognitive 20): ComponentFactoryGenerator.GetForwarderInfos has cognitive complexity 20 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":4646}}}],"partialFingerprints":{"codehealthFindingId/v1":"8aa99661380eb0eb88ab9f9b53ab03ab3f61a16b13472df4bd4b2a9d7e7a3c2f"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.GetOrphanCandidate (cognitive 20): RoutesGenerator.GetOrphanCandidate has cognitive complexity 20 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":499}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dc4a4ab25409a090415681fa8c22782e5449570c77be7369bc128f7420d714e"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskEndpointExtensions.UseRask (cognitive 20): RaskEndpointExtensions.UseRask has cognitive complexity 20 (threshold 15). Most of this is not in the body itself: 7 of the 20 points are its own statements and the rest belongs to one function literal inside it that branches (line 521). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":455}}}],"partialFingerprints":{"codehealthFindingId/v1":"e50288f8b34daa6361c8286fcfe893d9284faa6f0ca6bf3c156bd7894abe3af1"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskSpaEndpointExtensions.UseRaskSpa (cognitive 20): RaskSpaEndpointExtensions.UseRaskSpa has cognitive complexity 20 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 4 belong to 2 function literals inside it that branch. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/RaskSpaEndpointExtensions.cs"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"e661b7114f0e264721349b7168c7ce7a9ebec1aae7a4da0f47c639de4b67a334"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskApp.Build (cognitive 20): RaskApp.Build has cognitive complexity 20 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskApp.cs"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"6192152144453886f6e3f4e80b4172e13525ac01144670e015b9bc32a3a1ae46"}},{"ruleId":"D2","level":"warning","message":{"text":"TypeWalker.serializeUnion (cognitive 20): TypeWalker.serializeUnion has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 5, ternaries 2 (3 pts), loops 1 (nesting depth added 3). Of this number, 18 points are the body\u0027s own statements and 2 belong to 2 function literals inside it that branch. To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":601}}}],"partialFingerprints":{"codehealthFindingId/v1":"db7a843dfabd871f9aafc4330c207ceaa19a1bb9872d85abc3bcd3d14739d849"}},{"ruleId":"D2","level":"warning","message":{"text":"ApiClientGenerator.Emit (cognitive 19): ApiClientGenerator.Emit has cognitive complexity 19 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Api.Generators/ApiClientGenerator.cs"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff180da30c8ef13abe67017fffbe32e66c210b4b4d3115ad93d7c548c6900566"}},{"ruleId":"D2","level":"warning","message":{"text":"ApiClientGenerator.Compose (cognitive 19): ApiClientGenerator.Compose has cognitive complexity 19 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Api.Generators/ApiClientGenerator.cs"},"region":{"startLine":330}}}],"partialFingerprints":{"codehealthFindingId/v1":"678aee034add60b0112f5c968085078490789802b9eda037f430bdbbd66c2339"}},{"ruleId":"D2","level":"warning","message":{"text":"DevCommand.ExecuteAsync (cognitive 19): DevCommand.ExecuteAsync has cognitive complexity 19 (threshold 15). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DevCommand.cs"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"160e72ade7d1f7c946125789ca901a5cd389ce9f3e497a3cf057fc2081aea14e"}},{"ruleId":"D2","level":"warning","message":{"text":"Select.WriteAttributes (cognitive 19): Select.WriteAttributes has cognitive complexity 19 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Select.cs"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae78b22bebfa51602e9ef2e9b4ff6eeed1c31f34f44cdde002ef058734dbf191"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutePattern.TryMatch (cognitive 19): RoutePattern.TryMatch has cognitive complexity 19 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Routing/RoutePattern.cs"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"f11b5d67f94a3cc6c1049fe7efb02d4ec3dbde9f666974aa7eef461c203404f8"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelBuilderExtensions.MapValueCollections (cognitive 19): ModelBuilderExtensions.MapValueCollections has cognitive complexity 19 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/ModelBuilderExtensions.cs"},"region":{"startLine":309}}}],"partialFingerprints":{"codehealthFindingId/v1":"08a0be736bf0e3ddf8b5ad0418f3064a5ce031fcd878b3c9cddc926ac6c4f9fd"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.EmitCandidateResets (cognitive 19): ComponentFactoryGenerator.EmitCandidateResets has cognitive complexity 19 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":792}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffdea9d8f0d83f976e587286326c5a1b95fb57fa5b26ee0d2bcad09dd4e004ac"}},{"ruleId":"D2","level":"warning","message":{"text":"JsonScanner.TryReadString (cognitive 19): JsonScanner.TryReadString has cognitive complexity 19 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Json/JsonScanner.cs"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0b3fdc061608a6e576e904d4c6bafe55926ba30dc7ae6e0ba9098673ad5ab2d"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskEndpointExtensions.AttachAsync (cognitive 19): RaskEndpointExtensions.AttachAsync has cognitive complexity 19 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1755}}}],"partialFingerprints":{"codehealthFindingId/v1":"3200d91bc67c86b487ef12e10a467a73237a6a5bf1ff52898c12f60c5cbbb934"}},{"ruleId":"D2","level":"warning","message":{"text":"UiChartScale.Nice (cognitive 19): UiChartScale.Nice has cognitive complexity 19 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiChartScale.cs"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"97009bdcd3b0384ba5f4e71317ab4d9272b5fefc2b8f398c9586b1d57d1822f5"}},{"ruleId":"D2","level":"warning","message":{"text":"UiDataGrid.Rows (cognitive 19): UiDataGrid.Rows has cognitive complexity 19 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiDataGrid.cs"},"region":{"startLine":1175}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd639e7f4d6481c1fa9b104671fa6b795268313a2d9a2c770982c1a8362f94c0"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-deverror.showDevError (cognitive 19): rask-deverror.showDevError has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8 (10 pts), boolean chains 9 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-deverror.ts"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ff5680c38d8c0f7cf3c49be0bd330f66a5340c21ef27363a0a65d897936302b"}},{"ruleId":"D2","level":"warning","message":{"text":"flash.installFlash (cognitive 19): flash.installFlash has cognitive complexity 19 (threshold 15). Drivers by points: if/else 12 (13 pts), boolean chains 2, loops 2, ternaries 1 (2 pts) (nesting depth added 2). Of this number, 10 points are the body\u0027s own statements and 9 belong to 3 function literals inside it that branch. To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/flash.ts"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9873a8f349a3d280ffa22bc3913c22bb45e6843fdbfdc35ca18b7541344a816"}},{"ruleId":"D2","level":"warning","message":{"text":"extract-props.literalOf (cognitive 19): extract-props.literalOf has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (8 pts), ternaries 3 (7 pts), boolean chains 2, loops 1 (2 pts) (nesting depth added 8). Of this number, 17 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":1358}}}],"partialFingerprints":{"codehealthFindingId/v1":"90b7fd74d749f31c53612d6746fb8fc612173f83f8d8a33fc9d6a7da6f4ba2b7"}},{"ruleId":"D2","level":"warning","message":{"text":"GeneratedModelShape.EntitiesFor (cognitive 18): GeneratedModelShape.EntitiesFor has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/GeneratedModelShape.cs"},"region":{"startLine":361}}}],"partialFingerprints":{"codehealthFindingId/v1":"625bc0157e80744a079d3c685854da5b18d479fcb91bf8e51f597dd416ea8906"}},{"ruleId":"D2","level":"warning","message":{"text":"CqrsCodecGenerator.Authorization (cognitive 18): CqrsCodecGenerator.Authorization has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsCodecGenerator.cs"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"b65f5f9dba025b5b54b36c6485a4f9237e2f52f9467d8daa2a7791606c393273"}},{"ruleId":"D2","level":"warning","message":{"text":"ReadModelShape.Describe (cognitive 18): ReadModelShape.Describe has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/ReadModelShape.cs"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"2eeca002cfce1fc3cda3106c69d35ebeae2974770c85f563b7cff75737fb0d58"}},{"ruleId":"D2","level":"warning","message":{"text":"NewCommand.RetiredFlagError (cognitive 18): NewCommand.RetiredFlagError has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf92ceea6fab7e069b14428d62bf3617861e45770d9f3d595cffc545feedf850"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelGraphWalker.StepInto (cognitive 18): ModelGraphWalker.StepInto has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/ModelGraphWalker.cs"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fdea29c577b3065d5c89fb99b909aa070acfd8a20dce9f857e89b5f34978df5"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelGraphWalker.SplitPath (cognitive 18): ModelGraphWalker.SplitPath has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/ModelGraphWalker.cs"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"e701e1210003ba9929d970d66405c514124482cbf84ae5617847b645bd435dc3"}},{"ruleId":"D2","level":"warning","message":{"text":"ScopedAssetRegistry.EnsureBundle (cognitive 18): ScopedAssetRegistry.EnsureBundle has cognitive complexity 18 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedAssets/ScopedAssetRegistry.cs"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfdf115204e48eb0f96b563eeab0fb476c0eddf86d4d87459900857aeda1313b"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskCqrsEndpointExtensions.HandleAsync (cognitive 18): RaskCqrsEndpointExtensions.HandleAsync has cognitive complexity 18 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cqrs.Server/RaskCqrsEndpointExtensions.cs"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"1519c7e7db9c1f82a61e4f9cae567dec5ef4ecefbee18bb192a73935fb8fd72c"}},{"ruleId":"D2","level":"warning","message":{"text":"BlazorGenerator.Emit (cognitive 18): BlazorGenerator.Emit has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Blazor/BlazorGenerator.cs"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"6766df18b8990af15cbf52449dcac91ae18c64092ca841c1e64230bec3529d09"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.EmitBuilderEntries (cognitive 18): ComponentFactoryGenerator.EmitBuilderEntries has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":1693}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9a9b340443c7821bf6a56d7c234a16d6b1d2ea8d3498daeeae565464576b4b8"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentScopedCssGenerator.Emit (cognitive 18): ComponentScopedCssGenerator.Emit has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedCssGenerator.cs"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"808aa2a60355904b4ad2c386d081eb02534d54f62d1aa157c43e26a07258778b"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalGenerator.Describe (cognitive 18): ExternalGenerator.Describe has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"c31269ee93453b0f343b616dcae0b047ec0f34d5fb3bbed1cbd0a13fc518d3be"}},{"ruleId":"D2","level":"warning","message":{"text":"PackageIslandProps.Facts (cognitive 18): PackageIslandProps.Facts has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/PackageIslands/PackageIslandProps.cs"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"2736c7e32ff08b695d3e023b57148f15c02fdae864e28081219181914c28f990"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskEndpointExtensions.RunInSessionAsync (cognitive 18): RaskEndpointExtensions.RunInSessionAsync has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2065}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf21a6c9e766b0c8802f6a8c839dbf4f135c90ba09cefea0b6c2a8fc2230f7b7"}},{"ruleId":"D2","level":"warning","message":{"text":"HttpFetchDemo.OnMountAsync (cognitive 18): HttpFetchDemo.OnMountAsync has cognitive complexity 18 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Http/HttpFetchDemo.cs"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ff7c975610a6bb438c9424d4106559f73b07767efdce70a51d0532b73b19caa"}},{"ruleId":"D2","level":"warning","message":{"text":"UiKitDataInputDemo.Render (cognitive 18): UiKitDataInputDemo.Render has cognitive complexity 18 (threshold 15). Of this number, 14 points are the body\u0027s own statements and 4 belong to 5 function literals inside it that branch. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"d656f4016ce7e25eb5af09882fd3b83433046cf09b0fe3454f8124f82d5b1903"}},{"ruleId":"D2","level":"warning","message":{"text":"OrphanSweeper.SweepAsync (cognitive 18): OrphanSweeper.SweepAsync has cognitive complexity 18 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/OrphanSweeper.cs"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c40046c0c4b59fab0b97347c7d1755eabc82457627b5e9b6730f4616180fd85"}},{"ruleId":"D2","level":"warning","message":{"text":"lit.assign (cognitive 18): lit.assign has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/lit.ts"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"a42fe46e2a6d8ab379b7acee3dc1241d4ae21de047b7118638938873eedd2b3b"}},{"ruleId":"D2","level":"warning","message":{"text":"rask.applyDiffReply (cognitive 18): rask.applyDiffReply has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (15 pts), ternaries 2, boolean chains 1 (nesting depth added 6). Most of this is not in the body itself: 6 of the 18 points are its own statements and the rest belongs to one function literal inside it that branches (line 1445). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1444}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a45e1e4ae2ff2ee21a07ea415fd276a5fd1a92e73c95fc89d7f2e5e21ecb6ca"}},{"ruleId":"D2","level":"warning","message":{"text":"ApiCall.ReadProblem (cognitive 17): ApiCall.ReadProblem has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Api.Client/ApiCall.cs"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7575f19c56605003cc101f313b0d14805ab95e037132436e4f4df2a48970b69"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelInputGenerator.AggregateReferencesOf (cognitive 17): ModelInputGenerator.AggregateReferencesOf has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":309}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc5a6e79a7e189e4513fdc719a067d198e5ccf66e05a4583e94a0f3146a86d73"}},{"ruleId":"D2","level":"warning","message":{"text":"CliApplication.RunAsync (cognitive 17): CliApplication.RunAsync has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/CliApplication.cs"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cacc3a2d25fea46c732da881d15d3a2f4c12be7ed6892e4b66f12aaa4ca0213"}},{"ruleId":"D2","level":"warning","message":{"text":"SvgElement.WriteAttributes (cognitive 17): SvgElement.WriteAttributes has cognitive complexity 17 (threshold 15). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/SvgElement.cs"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e1a9336cdd58b2b7bf0b15bbadd6bfe331a43e103f8ace8e96d0f6d30be19a2"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalPackageScan.StringEnd (cognitive 17): ExternalPackageScan.StringEnd has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageScan.cs"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c8f3d06c7836c564348ebc55d6e112d5b8fb4eecd391ebc3a8207aa21b0a450"}},{"ruleId":"D2","level":"warning","message":{"text":"InternalRouteStringAnalyzer.TryAddPage (cognitive 17): InternalRouteStringAnalyzer.TryAddPage has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/InternalRouteStringAnalyzer.cs"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"517f2a710fdf9ad51c73efc87ae032fa8e53b4c5ad690fe4ee20244e63e4b7a1"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.ScanExternalEntries (cognitive 17): ComponentFactoryGenerator.ScanExternalEntries has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":4020}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd42ec030a1e0e94380e6cffcc405921dca2573ee839b1d8114ed455d09179c9"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.BuildConstraintsClause (cognitive 17): ComponentFactoryGenerator.BuildConstraintsClause has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":4806}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9f827e407f8910cb2cfd03189e0746a92b22f5c4ed92c2a0524b9c103865f8b"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.NormalizeTemplate (cognitive 17): RoutesGenerator.NormalizeTemplate has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":347}}}],"partialFingerprints":{"codehealthFindingId/v1":"4595bf03919df0f8b7461301185e92d3613a588c117fb3b4a65297a16cdeb564"}},{"ruleId":"D2","level":"warning","message":{"text":"LogScopes.Flatten (cognitive 17): LogScopes.Flatten has cognitive complexity 17 (threshold 15). The drivers above price the dispatch low by construction \u2014 a dispatch is charged once however many cases it lists, while each branch inside an arm is charged in full \u2014 so most of this count is what the case bodies hold, and the arms are where it can be reduced. To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Logging/LogScopes.cs"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8ff8790112a83b71feacd1b60cbd2f5dbfec36a0c95fcd4414c5e8b7933302a"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskEndpointExtensions.EnforceAuthAndRenderAsync (cognitive 17): RaskEndpointExtensions.EnforceAuthAndRenderAsync has cognitive complexity 17 (threshold 15). To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2554}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dd782635c4b3546548c432f37b51478a926bfc36bea56cacc37abd3a954976b"}},{"ruleId":"D2","level":"warning","message":{"text":"SqliteBusyRetry.ExecAsync (cognitive 17): SqliteBusyRetry.ExecAsync has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite/SqliteBusyRetry.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a5e70dc9de398f2a79bf31e62893cd5a07947f5650e50a6bd825b44e4f80a87"}},{"ruleId":"D2","level":"warning","message":{"text":"SqlitePragmas.BuildScript (cognitive 17): SqlitePragmas.BuildScript has cognitive complexity 17 (threshold 15). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite/SqlitePragmas.cs"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"75ee71d16523c9a7b0a43142e44ebf818f4e7f89ff720e106674e71a119656d5"}},{"ruleId":"D2","level":"warning","message":{"text":"UiDataGrid.ResolveQuery (cognitive 17): UiDataGrid.ResolveQuery has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiDataGrid.cs"},"region":{"startLine":755}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebca103fd5482047ac2483933cd340944d75d822b631dc59dc46f6dd4f689573"}},{"ruleId":"D2","level":"warning","message":{"text":"UiFileInput.Render (cognitive 17): UiFileInput.Render has cognitive complexity 17 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiFileInput.cs"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"adbe40e879fd4aa07ebbc9380c28ce4bc5a31092d72219e56a776812001d9019"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskApiValidation.ValidateEndpointAsync (cognitive 17): RaskApiValidation.ValidateEndpointAsync has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/ApiValidation.cs"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b6cfaaef5e0c46671906814b562d340f2848da06ff4504b13358757dc93e464"}},{"ruleId":"D2","level":"warning","message":{"text":"ActionFilter.OnActionExecutionAsync (cognitive 17): ActionFilter.OnActionExecutionAsync has cognitive complexity 17 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/ApiValidation.cs"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddfcf805af9769ea89f3a6e97e805a49c30f1cc34563d787735166237a66b1b3"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-dom.syncFormProperty (cognitive 17): rask-dom.syncFormProperty has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (13 pts), boolean chains 4 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"65769a02c3aac072b30ac6235c5e69790f6149119ac9a0e7ed5aac612d3cd03e"}},{"ruleId":"D2","level":"warning","message":{"text":"extract-props.synthesizeEmits (cognitive 17): extract-props.synthesizeEmits has cognitive complexity 17 (threshold 15). Drivers by points: if/else 2 (6 pts), ternaries 2 (5 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":1399}}}],"partialFingerprints":{"codehealthFindingId/v1":"70765eb98dc43f64c0bb605069d28752a9290305837aa4f5675f9d81bdb324b6"}},{"ruleId":"D2","level":"warning","message":{"text":"rask.restoreOneField (cognitive 17): rask.restoreOneField has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (10 pts), loops 2 (4 pts), boolean chains 2, ternaries 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":837}}}],"partialFingerprints":{"codehealthFindingId/v1":"a235b876abcce6950d1cdb9d9eee5eefc3fe4fca515ab42b512f0386631428f9"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelStateMutationAnalyzer.CanNarrow (cognitive 16): ModelStateMutationAnalyzer.CanNarrow has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/Analyzers/ModelStateMutationAnalyzer.cs"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ff5cde4a42a1bd63c2e34a1f9a13ed9a183046b0d29d91a588eebcf585fd4e7"}},{"ruleId":"D2","level":"warning","message":{"text":"CqrsDispatchGenerator.Emit (cognitive 16): CqrsDispatchGenerator.Emit has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsDispatchGenerator.cs"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5113361971271250a96a90e3c70286ef493082c9124e9d437c81998e68f86d6"}},{"ruleId":"D2","level":"warning","message":{"text":"ModelRegistryGenerator.EmitConventions (cognitive 16): ModelRegistryGenerator.EmitConventions has cognitive complexity 16 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelRegistryGenerator.cs"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"703f9817277c758c9eb6a9d9336273082934e765f8e65f190eba34174a86a71f"}},{"ruleId":"D2","level":"warning","message":{"text":"ReadModelGenerator.EmitFace (cognitive 16): ReadModelGenerator.EmitFace has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ReadModelGenerator.cs"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"2eb4e72a1a70f9014e360b035497b82c1e27e29ccf5f5f4a29b8516c9288e0c2"}},{"ruleId":"D2","level":"warning","message":{"text":"Component.RenderAsLiveRootCore (cognitive 16): Component.RenderAsLiveRootCore has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":2594}}}],"partialFingerprints":{"codehealthFindingId/v1":"208b5efd50c62b994d1b82b708caf7bc40364313a19ddde965f10700ec11e936"}},{"ruleId":"D2","level":"warning","message":{"text":"DataAnnotationsFieldValidator.ResultsFor (cognitive 16): DataAnnotationsFieldValidator.ResultsFor has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/DataAnnotationsFieldValidator.cs"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a52f9db4a00573d9eb4460c42500e331d45234e377382539b63d540bb7e4113"}},{"ruleId":"D2","level":"warning","message":{"text":"LivePayload.IndexOfBodyOpenUtf8 (cognitive 16): LivePayload.IndexOfBodyOpenUtf8 has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":1015}}}],"partialFingerprints":{"codehealthFindingId/v1":"21b29b577f416e59569f15218b87beba0f05a427879b59db23fe053c4c02de04"}},{"ruleId":"D2","level":"warning","message":{"text":"PageBinder.TryGetRawValue (cognitive 16): PageBinder.TryGetRawValue has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Routing/PageBinder.cs"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"563333f1169e7fa45e58627ea20bb43de8378d19473fc9f58ca034057374913c"}},{"ruleId":"D2","level":"warning","message":{"text":"RemoteDispatch.UploadLargeFilesAsync (cognitive 16): RemoteDispatch.UploadLargeFilesAsync has cognitive complexity 16 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, flatten the nesting: invert conditions into early returns or guard clauses so the happy path stays at one level, and lift the deepest nested block into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cqrs.Client/RemoteDispatch.cs"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"be142626e5fa7d27e6f3041b58d01dc8e643cf156647dad1b9dea476868fec2e"}},{"ruleId":"D2","level":"warning","message":{"text":"SystemPage.BackupStats (cognitive 16): SystemPage.BackupStats has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Dashboard/Pages/SystemPage.cs"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"939c69b534c0ae27f15b8996c9ae090804c2d35328a8701fedd43f32e63f713a"}},{"ruleId":"D2","level":"warning","message":{"text":"Builder.Builder.ctor (cognitive 16): Builder.Builder.ctor has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Probe/DevToolsComponentNode.cs"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"52a4cb4afe6fe72f9730525dc0be5a00d072f5c47a92b3d2fb1c39ad40c972b4"}},{"ruleId":"D2","level":"warning","message":{"text":"Builder.AddRange (cognitive 16): Builder.AddRange has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Probe/DevToolsComponentNode.cs"},"region":{"startLine":467}}}],"partialFingerprints":{"codehealthFindingId/v1":"74a02b838da419a3b55c6e52b01f4bc6861c3fd4e8e3775f8fe41609857e64b0"}},{"ruleId":"D2","level":"warning","message":{"text":"ExternalBuildPlan.EntryModule (cognitive 16): ExternalBuildPlan.EntryModule has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalBuildPlan.cs"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"ede6a3e32f978cec981ba7e866f3e918dccf59655d88a4fba35f25bab02d5c3d"}},{"ruleId":"D2","level":"warning","message":{"text":"SyncExternalPropsSnapshotsTask.Execute (cognitive 16): SyncExternalPropsSnapshotsTask.Execute has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/SyncExternalPropsSnapshotsTask.cs"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"9115059b8df69b318c7918a7ad4b90567722665a6604815e9ada2b5624e9edb7"}},{"ruleId":"D2","level":"warning","message":{"text":"DuplicateAddRaskAnalyzer.Analyze (cognitive 16): DuplicateAddRaskAnalyzer.Analyze has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/DuplicateAddRaskAnalyzer.cs"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"afd6290fc59d414f5b1ab3b222f643ba47f0dac98b27991858d1e95c17b420df"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.PinSets (cognitive 16): ComponentFactoryGenerator.PinSets has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":2860}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f972af8a6291ffb1ad0a83e5da001729ad3f79ac7a115372ef5a9b17ff3ba23"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.GetCandidate (cognitive 16): ComponentFactoryGenerator.GetCandidate has cognitive complexity 16 (threshold 15). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":4493}}}],"partialFingerprints":{"codehealthFindingId/v1":"1de3596d129682460bf05a50dc15875c5d642309199b355ad7b9009d7b43dd46"}},{"ruleId":"D2","level":"warning","message":{"text":"ComponentFactoryGenerator.OverridesLifecycleHook (cognitive 16): ComponentFactoryGenerator.OverridesLifecycleHook has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":4945}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bab623c0cf9e5aea4550db8046460fb372256ca4b7977a2df16a44fd7cf2732"}},{"ruleId":"D2","level":"warning","message":{"text":"RoutesGenerator.PathParamTypeFqn (cognitive 16): RoutesGenerator.PathParamTypeFqn has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":1344}}}],"partialFingerprints":{"codehealthFindingId/v1":"417f2c45ba23c419d449efe1aa1c9a62cda525c94f02800e90f57b25524a84b2"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskEndpointExtensions.ReceiveFramesAsync (cognitive 16): RaskEndpointExtensions.ReceiveFramesAsync has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1198}}}],"partialFingerprints":{"codehealthFindingId/v1":"587eb625a11d97e93943d00272a57bba3416d5c7114495313e049f4149d12d82"}},{"ruleId":"D2","level":"warning","message":{"text":"RaskEndpointExtensions.HandleUploadAsync (cognitive 16): RaskEndpointExtensions.HandleUploadAsync has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":3035}}}],"partialFingerprints":{"codehealthFindingId/v1":"40773c1a382085689bb146b45d82aefddd14bcdc05a3329f4cd3762fb34ab30a"}},{"ruleId":"D2","level":"warning","message":{"text":"UiDataGrid.Band (cognitive 16): UiDataGrid.Band has cognitive complexity 16 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiDataGrid.cs"},"region":{"startLine":1296}}}],"partialFingerprints":{"codehealthFindingId/v1":"693b985762b9d052b8590d9c0061d95897b4b9e3026eef1b08e5f5a7340a710c"}},{"ruleId":"D2","level":"warning","message":{"text":"UiNavTab.Render (cognitive 16): UiNavTab.Render has cognitive complexity 16 (threshold 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiNavTab.cs"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"a77e0666187166d23a2ff3d1254b17a22cec73efc51025cb973358c8cdd866df"}},{"ruleId":"D2","level":"warning","message":{"text":"gamepad.watch (cognitive 16): gamepad.watch has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (10 pts), boolean chains 2, loops 1 (2 pts), ternaries 1 (2 pts) (nesting depth added 7). Most of this is not in the body itself: 2 of the 16 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 48, 78, 91). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/gamepad.ts"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"c00ac051709efd382206b10274bde5b1b2d16079925aa721ce671768fb4812f7"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-morph.raskApplySelectSelection (cognitive 16): rask-morph.raskApplySelectSelection has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (10 pts), loops 3 (5 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0ade2ad4b563d91dd00cb8d1dabd5f4499736cc3cad3d4365f80e12514be68f"}},{"ruleId":"D2","level":"warning","message":{"text":"extract-props.propsOf (cognitive 16): extract-props.propsOf has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 2 (4 pts), boolean chains 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":383}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4c4faeab2f589847165b54133ef4fb8a2929a0bf4bf3b0a83f801017c6e0f0d"}},{"ruleId":"D2","level":"warning","message":{"text":"rask-http-transport.createSseParser (cognitive 16): rask-http-transport.createSseParser has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (11 pts), boolean chains 2, ternaries 2, loops 1 (nesting depth added 3). Of this number, 10 points are the body\u0027s own statements and 6 belong to one function literal inside it that branches. To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask-http-transport.ts"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"30228f5a3ab2a554cd27b6e2404d4579ba8fb5d665db2eb7b1dc052d9d913b78"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ComponentFactoryGenerator: TooManyMethods \u2014 2467 significant lines (blank, comment-only and punctuation-only lines excluded), 159 methods. The bar is 30 methods; this is 129 over it, 5.30\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6576827800e4037f997d9c0a75569acb438e32e7ab6054d490589b695d315335"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Rask.Generators/ComponentFactoryGenerator.cs: FileTooLong \u2014 2627 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 2127 over it, 5.25\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd92f4da23baf6bf3f0eebd5a9d00dd7f7ed1426ec5550b0b9372ae87c645bcd"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: ModelInputGenerator.Render: MethodTooLong \u2014 Render runs 410 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 310 over it, 4.10\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":686}}}],"partialFingerprints":{"codehealthFindingId/v1":"88dff63aa117b6760de7cdc92ec070a0b3961c3736884dd9b21e8da1278ec9b2"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Component: TooManyMethods \u2014 1066 significant lines (blank, comment-only and punctuation-only lines excluded), 111 methods, declared across 2 files: Rask.Core/Component.cs (108), Builder/BuilderEntries.cs (3). The bar is 30 methods; this is 81 over it, 3.70\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"01f50630cc92a428286e059ee6952104eb566e1ad3ec60ecd102ba50e848e58b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Rask.Server/RaskEndpointExtensions.cs: FileTooLong \u2014 1459 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 959 over it, 2.92\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c55ba296309e44dcdbcad9ba027e0138e65cc378e987bb4958a28401338bb585"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: UiIcon.Shapes: MethodTooLong \u2014 Shapes runs 285 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 185 over it, 2.85\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiIcon.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc1d23d7b2db96c241fd6209e2a03b22cb4d01a8292a32e5fef8b8c520d8d4c3"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: UiKitDataInputDemo.Render: MethodTooLong \u2014 Render runs 265 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 165 over it, 2.65\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"f555b221bafb03c0408bd30b0636fdfae58b109b83caf9dae8251370e3825659"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: UiClassNames: TooManyMethods \u2014 557 significant lines (blank, comment-only and punctuation-only lines excluded), 76 methods. The bar is 30 methods; this is 46 over it, 2.53\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiClassNames.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"034be1e1134865742937224318f6948e51534e3a47a48df581f992325fe9af49"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: UiDataGrid: TooManyMethods \u2014 716 significant lines (blank, comment-only and punctuation-only lines excluded), 72 methods. The bar is 30 methods; this is 42 over it, 2.40\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiDataGrid.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"485736fffabded00a75bded6367aff0f4c96d954e7c4fbb834cb3c6cc7764bc2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Rask.Batteries.Generators/ModelInputGenerator.cs: FileTooLong \u2014 1144 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 644 over it, 2.29\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e94aac357806111b38a129254809915171625dbb62907df2ec058f581368eca"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Resources/rask.ts: FileTooLong \u2014 1136 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 636 over it, 2.27\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a628e56184d4e8adbad68ba53705a20e079c0e41e2cf49cf4152653102187310"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: RaskEndpointExtensions: TooManyMethods \u2014 1396 significant lines (blank, comment-only and punctuation-only lines excluded), 67 methods. The bar is 30 methods; this is 37 over it, 2.23\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f29dff9f254e29f7484b3c0b8e3f3f807b1512bbd7bd9b89653e38aa6920767"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Rask.Core/Component.cs: FileTooLong \u2014 1110 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 610 over it, 2.22\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"503d5cf1a63a6b3797496d2772241b6342668d41e8b525c61060dc73b7b4103a"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: RoutesGenerator: ClassTooLong \u2014 841 significant lines (blank, comment-only and punctuation-only lines excluded), 29 methods. The bar is 400 significant lines; this is 441 over it, 2.10\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"608ecf5c3642ef5435ecb6c52150ac88bf750c33d46a80795759914697845fc9"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: UiKitActionsDemo.Render: MethodTooLong \u2014 Render runs 209 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 109 over it, 2.09\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitActionsDemo.cs"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"02a7f2ca44897b19b1572c3c5a7b90b09bf6b7acad04ef6b5b052df246b83471"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: DeployCommand: TooManyMethods \u2014 737 significant lines (blank, comment-only and punctuation-only lines excluded), 62 methods, declared across 2 files: Commands/DeployCommand.cs (49), Commands/DeployCommand.Ops.cs (13). The bar is 30 methods; this is 32 over it, 2.07\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DeployCommand.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d3e6429f80941cc27501ddc97fef77c8716eaa1364bfc218808d6ae91333b11"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: extractor/extract-props.ts: FileTooLong \u2014 928 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 428 over it, 1.86\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c65c47659e31476ff275579972bdd994911406dfad43d8414914cf7d975173d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Rask.Generators/RoutesGenerator.cs: FileTooLong \u2014 907 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 407 over it, 1.81\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd6066a85fbe06c027e082527a155a5a690aaf852ce87226b28cfed932e091c5"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: Component.TryInvokeHandlerCoreAsync: MethodTooLong \u2014 TryInvokeHandlerCoreAsync runs 163 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 63 over it, 1.63\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":2270}}}],"partialFingerprints":{"codehealthFindingId/v1":"1601c5fce31a3563b4623c21598116bbbc737b4736412055bf0219d3191e1f65"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: ExternalGenerator.Emit: MethodTooLong \u2014 Emit runs 154 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 54 over it, 1.54\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":792}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f18d2ead5e521c8c895c9d51e9a026a82b6eace4286468245f92fc2352907d8"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: PwaPage.Sections: MethodTooLong \u2014 Sections runs 151 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 51 over it, 1.51\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/PwaPage.cs"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"f888c323997478d1d5f7f2c109f43bb89bc62f1d6a9e1b996ee8bb7f21544e13"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Resources/rask-dom.ts: FileTooLong \u2014 753 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 253 over it, 1.51\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"54235dc25c562cde2a2094328c9b002427bfa2ae076362e141d2ff4bd4107034"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Rask.Ui/UiDataGrid.cs: FileTooLong \u2014 723 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 223 over it, 1.45\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiDataGrid.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b166cf2001180463c5384884ceaedfc6cd0bfd62964af77baa2394ced893a53"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: ExternalGenerator: ClassTooLong \u2014 575 significant lines (blank, comment-only and punctuation-only lines excluded), 19 methods. The bar is 400 significant lines; this is 175 over it, 1.44\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"544bfed7abd5134fde11df75be64e4d64db7a5b6e0b06503088cd326c1a88eac"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: FrameDiffer.DiffKeyedSiblings: MethodTooLong \u2014 DiffKeyedSiblings runs 139 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 39 over it, 1.39\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":814}}}],"partialFingerprints":{"codehealthFindingId/v1":"633de095f16fa1a94a22c132dcf9ec829bb185eee6c5e5f692a449a77ca84fcc"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: CqrsCodecGenerator.Build: MethodTooLong \u2014 Build runs 135 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 35 over it, 1.35\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsCodecGenerator.cs"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"7dcd4f7d1fe864154492784694858d6ae370157524edead19358875b331f4dd4"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: EditContext: TooManyMethods \u2014 365 significant lines (blank, comment-only and punctuation-only lines excluded), 40 methods. The bar is 30 methods; this is 10 over it, 1.33\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/EditContext.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aca86ef5cae995a696ce83e7cd91fda3bbf843e3eeb590aab3f2dca564f9eb97"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: NewCommand: ClassTooLong \u2014 532 significant lines (blank, comment-only and punctuation-only lines excluded), 24 methods. The bar is 400 significant lines; this is 132 over it, 1.33\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6caf73eb9904f7fb950bf93223a6ab03b5000590b4ff866bdee440e6d06e4a0"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: client.httpTransport: FunctionTooLong \u2014 httpTransport runs 133 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 33 over it, 1.33\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/client/client.ts"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"98df1e32480f49d9d7923ffbc651acf8920bd2d380fb8a81187f2311b2440d32"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: panel-client.installPanelClient: FunctionTooLong \u2014 installPanelClient runs 128 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 28 over it, 1.28\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/panel/panel-client.ts"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"25aa3c8e7d16551c4736fba21e9d3ad0198113e903f8813a6b4d896d0d272f98"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: LivePayload: ClassTooLong \u2014 508 significant lines (blank, comment-only and punctuation-only lines excluded), 29 methods. The bar is 400 significant lines; this is 108 over it, 1.27\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc6696481b18459e810d05db8676a4cf98214a97ed897b0034748222d886921c"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: DbCommand: ClassTooLong \u2014 507 significant lines (blank, comment-only and punctuation-only lines excluded), 30 methods, declared across 2 files: Commands/DbCommand.Backup.cs (22), Commands/DbCommand.cs (8). The bar is 400 significant lines; this is 107 over it, 1.27\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DbCommand.Backup.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d30aff0608e51544fac7021c5c3a8bce0630d1797254ac65a81b805b363eda76"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: TranslationCatalogGenerator: ClassTooLong \u2014 492 significant lines (blank, comment-only and punctuation-only lines excluded), 22 methods. The bar is 400 significant lines; this is 92 over it, 1.23\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/TranslationCatalogGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdefb1795ff764b8a13ade9c45c05ed9d17db7948de640391596baf2a2df4233"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: External/ExternalGenerator.cs: FileTooLong \u2014 610 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 110 over it, 1.22\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9c8de79c9462ac191d804702013ba4f03ba5d9d7d39ebf02c476676f70be4ba"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: Input.WriteAttributes: MethodTooLong \u2014 WriteAttributes runs 121 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 21 over it, 1.21\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Input.cs"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"a90b9111fa8c329d829cdda1f697853b11dc84ca1ca65cad7e5ee12ee916c76c"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Commands/DeployCommand.cs: FileTooLong \u2014 589 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 89 over it, 1.18\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DeployCommand.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0167d3fd39964f1dc1fafff0d664e928b6ad686c2bd0022a473c95fa0d8d26d"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: ComponentFactoryGenerator.GetFactoryProperties: MethodTooLong \u2014 GetFactoryProperties runs 117 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 17 over it, 1.17\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":5119}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e3d0a4177f3eaa2e533022af1c93c0e1bc8dd9f9fe45a5f40d22dee4e2787a6"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ModelInputGenerator: TooManyMethods \u2014 1051 significant lines (blank, comment-only and punctuation-only lines excluded), 35 methods. The bar is 30 methods; this is 5 over it, 1.17\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b25c11ec09fe2349fc5e2d7bd9b94f6d15ec938926dee9bfd8140f61df8e166f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: LiveSession: TooManyMethods \u2014 294 significant lines (blank, comment-only and punctuation-only lines excluded), 35 methods. The bar is 30 methods; this is 5 over it, 1.17\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/LiveSession.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29134f4395400adf6ac01de5c2b832a270dffb7df2731a6143c69125540f98dc"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: GuideCatalog: ClassTooLong \u2014 454 significant lines (blank, comment-only and punctuation-only lines excluded), 4 methods. The bar is 400 significant lines; this is 54 over it, 1.14\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Guides/GuideCatalog.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"05a60d324263ab0a51011db230dfb5d9b4afd822eb24cbc300f817b4475ccbaa"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: WireJson: TooManyMethods \u2014 120 significant lines (blank, comment-only and punctuation-only lines excluded), 34 methods. The bar is 30 methods; this is 4 over it, 1.13\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wire/WireJson.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a7d21df23ed21a723129c4f1e198994915f9d9b99a3e1ba43fd0d35255ff079"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Rask.Ui/UiClassNames.cs: FileTooLong \u2014 558 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 58 over it, 1.12\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiClassNames.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c896587312dc71668aa3b5e7a0ced57fe28f2fcf2845062cdb1b6e83919dc21"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: FrameDiffer: ClassTooLong \u2014 444 significant lines (blank, comment-only and punctuation-only lines excluded), 19 methods. The bar is 400 significant lines; this is 44 over it, 1.11\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b61a06e0d3ceb15a2e328abcd956250c881e7e5a18dbc32d5e4a3868d270f20"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: FrameDiffer.DiffSiblings: MethodTooLong \u2014 DiffSiblings runs 111 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 11 over it, 1.11\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee14645e98395d2abb306e5b8ab3bec51f8e0cf1c2275d5d5e82db6855a5887e"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: UiKitDataDisplayDemo.Render: MethodTooLong \u2014 Render runs 111 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 11 over it, 1.11\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitDataDisplayDemo.cs"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe4f87b66410259970ee9faa4924eba2ddb1415eb162271543e4bae77c3c21b1"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ModelQuery: TooManyMethods \u2014 116 significant lines (blank, comment-only and punctuation-only lines excluded), 33 methods. The bar is 30 methods; this is 3 over it, 1.10\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/ModelQuery.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f46bd2a0e0d1955225c8bb23cf08ad535f8c778cc9cef3f9bf9c8d2836898de6"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: DeployCommand.ExecuteAsync: MethodTooLong \u2014 ExecuteAsync runs 108 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 8 over it, 1.08\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DeployCommand.cs"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef62ca14c806080ce6484471f670218122d35675944a62853e3d97c9f8d2ad02"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: ModelRegistryGenerator: ClassTooLong \u2014 430 significant lines (blank, comment-only and punctuation-only lines excluded), 19 methods. The bar is 400 significant lines; this is 30 over it, 1.08\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelRegistryGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a51f86c6c42b00cc96c245aa556d408ab5b3de876f44f28305f51d0d59d86418"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Commands/NewCommand.cs: FileTooLong \u2014 537 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 37 over it, 1.07\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c7434813c17bb521c943f1e85f4db19197095889df0d613f25b58bdbb680700"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: LivePayload.BuildPayloadUtf8Diff: MethodTooLong \u2014 BuildPayloadUtf8Diff runs 107 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 7 over it, 1.07\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9b825c4786fad34700c87abcf288b3d2eaa42f6628bcd3bd4bbb48788a22c2d"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: GeneratedModelShape: TooManyMethods \u2014 242 significant lines (blank, comment-only and punctuation-only lines excluded), 32 methods. The bar is 30 methods; this is 2 over it, 1.07\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/GeneratedModelShape.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcc88ab174a197803ba239eb40fcc86c4cb6e88834d9f57d470bc1416dfaf15a"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: LiveRenderContext: TooManyMethods \u2014 183 significant lines (blank, comment-only and punctuation-only lines excluded), 32 methods. The bar is 30 methods; this is 2 over it, 1.07\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LiveRenderContext.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"22ba438f55126c2fbac15c556627e853d3cb8b44168bb85f6d4eebc48b6813d4"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Resources/rask.wasm.ts: FileTooLong \u2014 532 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 32 over it, 1.06\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask.wasm.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"374cf737adfc1b841b2991ca9a3e480f406a3d701b62f0031d61497c009a043d"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: RaskEndpointExtensions.RunSocketLoop: MethodTooLong \u2014 RunSocketLoop runs 106 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 6 over it, 1.06\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1357}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d3b6e7265cb8df27b862ebb1e583de83ffcc5760680e24b88b741be7e077234"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: ApiClientGenerator: ClassTooLong \u2014 415 significant lines (blank, comment-only and punctuation-only lines excluded), 22 methods. The bar is 400 significant lines; this is 15 over it, 1.04\u00D7 the bar. The type holds no instance state, so there is no shared data to group its members by. To reduce it, split it by area instead: give each cohesive family of members its own smaller type, so no one type has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Api.Generators/ApiClientGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb3c1decafb6273b2132b1473ec44fb2aa5c20c7c8ee2e49c43c3debb3511b87"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Live/LivePayload.cs: FileTooLong \u2014 515 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 15 over it, 1.03\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d792bcb7ec490e768bdac64d390bdf25e9e6fe75bdeaae75da4b08b924aa1aeb"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: rask-morph.morph: FunctionTooLong \u2014 morph runs 103 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 3 over it, 1.03\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"81aabfddc6e762243b8e14fa14064d4ed5860a10a660fe81177205414d6e4af5"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Live/FrameDiffer.cs: FileTooLong \u2014 514 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 14 over it, 1.03\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8384c0c71d1b21346debd3e2bb7ac2bb9fb6933bc5923998aca5be034561fd69"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: UiKitLayoutDemo.Render: MethodTooLong \u2014 Render runs 101 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 1 over it, 1.01\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitLayoutDemo.cs"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcbc389d66a9b5c6ffd40308c71169658710ee3d28e99c5eb44de7bbf66cf424"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: overlay.installOverlay: FunctionTooLong \u2014 installOverlay runs 101 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 1 over it, 1.01\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/overlay.ts"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"df08db84facd5f12ea516696ffb45f5b773342cc78ee003d5337d72178ab5b8f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: Translations/TranslationCatalogGenerator.cs: FileTooLong \u2014 503 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 3 over it, 1.01\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/TranslationCatalogGenerator.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"96da15c6653c231ba7e44ae963fc1600423e063fe041274d43ceb85a2042ec07"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): src/Rask.Generators/ComponentFactoryGenerator.cs:139-256 | src/Rask.Generators/ComponentScopedCssGenerator.cs:51-69 | src/Rask.Generators/ComponentScopedJsGenerator.cs:102-145 | src/Rask.Generators/RoutesGenerator.cs:193-229 \u2014 These 4 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 4 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 4 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d9a06328cec2bf2e360fed1b975bc81eaafd4b0ef3faf0e6bca21b758e28309"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (38\u201344 lines \u00D7 3): src/Rask.Jobs/JobProcessor.cs:62-105 | src/Rask.Mail/MailProcessor.cs:51-88 | src/Rask.Outbox/OutboxProcessor.cs:48-85 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobProcessor.cs\u0060 and \u0060src/Rask.Mail/MailProcessor.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Jobs/JobProcessor.cs:62\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobProcessor.cs"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"95dcdac24a5addbaef3c2baef701162e3360c2f83d583e719e241ec92e80116f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (39\u201341 lines \u00D7 3): src/Rask.Jobs/JobProcessor.cs:458-496 | src/Rask.Mail/MailProcessor.cs:343-381 | src/Rask.Outbox/OutboxProcessor.cs:347-387 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobProcessor.cs\u0060 and \u0060src/Rask.Mail/MailProcessor.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Jobs/JobProcessor.cs:458\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobProcessor.cs"},"region":{"startLine":458}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fc2a6483ee23051646c8b79dc6e11e9d0a37755ecc373a57b57009f6fa0ec84"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (39\u201341 lines \u00D7 2): src/Rask.Core/Components/Button.cs:114-154 | src/Rask.Core/Components/Input.cs:408-446 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Button.cs:114\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Button.cs"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ec43cb5a755b69c4ade038a32ecac7d805c6719f536bb26e9395729448a3326"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201336 lines \u00D7 2): src/Rask.Core/Component.cs:1834-1869 | src/Rask.Core/Component.cs:1880-1902 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Component.cs:1834\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":1834}}}],"partialFingerprints":{"codehealthFindingId/v1":"70e3909b537ac9d63e349f4187d8e7e83101456609243f0fa70d8221e7e0b037"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (36 lines \u00D7 2): src/Rask.Ui/UiMultiSelect.cs:68-110 | src/Rask.Ui/UiSelect.cs:122-157 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiMultiSelect.cs"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e05a6d626a8f66fd8734b4da3a72ffb824714c837ed03d0aef7a8adc85acd67"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32\u201333 lines \u00D7 2): src/Rask.Auth.Client/BrowserAuth.cs:97-129 | src/Rask.Auth/ServerAuth.cs:93-124 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Auth.Client/BrowserAuth.cs:97\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Auth.Client/BrowserAuth.cs"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"982d5592069fc355f46d2467057bc94c2ddb13a486f372ba3dc4689d55560de8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28\u201333 lines \u00D7 2): src/Rask.Core/Components/Button.cs:30-62 | src/Rask.Core/Components/Input.cs:119-146 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Button.cs"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc7f3352f0b68fec4ffd3696fd908a4e3a45238f05922210c30d168cfcb1b1bc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): src/Rask.Core/Components/Svg/SvgText.cs:61-93 | src/Rask.Core/Components/Svg/Tspan.cs:41-73 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Svg/SvgText.cs:61\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/SvgText.cs"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c16a645d73ca1bc806d85b6a8105cdaadfd54f0df0583223006a99423ad1a62"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201332 lines \u00D7 3): src/Rask.Ui/UiCalendar.cs:42-73 | src/Rask.Ui/UiCalendarMultiple.cs:25-49 | src/Rask.Ui/UiCalendarRange.cs:25-49 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiCalendar.cs"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"83bd31bbcde06b4231572fcd0370ee184a2e1e37b33669be1fc1fc5ddb701658"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): src/Rask.Jobs/JobOptions.cs:7-36 | src/Rask.Mail/MailOptions.cs:61-90 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobOptions.cs\u0060 and \u0060src/Rask.Mail/MailOptions.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobOptions.cs"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"11d0e17beec23cc9847ba9a5195609dfd7a360f4b84f95e72369d6646bbf9a65"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): src/Rask.Jobs/JobSerializerRegistry.cs:60-89 | src/Rask.Outbox/OutboxSerializerRegistry.cs:60-89 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobSerializerRegistry.cs\u0060 and \u0060src/Rask.Outbox/OutboxSerializerRegistry.cs\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 91 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobSerializerRegistry.cs"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ce9018d768f4def495021f76435aef58bb23feb5c834cc6aff87a9543f6ddba"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26\u201330 lines \u00D7 2): src/Rask.Ui/UiRadio.cs:30-59 | src/Rask.Ui/UiToggle.cs:26-51 \u2014 before extracting anything, compare \u0060src/Rask.Ui/UiRadio.cs\u0060 and \u0060src/Rask.Ui/UiToggle.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 90 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiRadio.cs"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"087816f59373a491d78f6fe1dd6e2df534a62d0957f4c74be61d4f2bfd01203e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): src/Rask.Generators/ComponentScopedCssGenerator.cs:72-100 | src/Rask.Generators/ComponentScopedJsGenerator.cs:148-176 \u2014 before extracting anything, compare \u0060src/Rask.Generators/ComponentScopedCssGenerator.cs\u0060 and \u0060src/Rask.Generators/ComponentScopedJsGenerator.cs\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/ComponentScopedCssGenerator.cs:72\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedCssGenerator.cs"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8ae0f48caab04e65d79bfaa53a66fa5d6ac6bacaec9edae230e45c6fb69dc56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201328 lines \u00D7 3): src/Rask.Ui/UiMenuCheckbox.cs:32-49 | src/Rask.Ui/UiRadio.cs:36-63 | src/Rask.Ui/UiToggle.cs:32-55 \u2014 before extracting anything, compare \u0060src/Rask.Ui/UiRadio.cs\u0060 and \u0060src/Rask.Ui/UiToggle.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 90 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiMenuCheckbox.cs"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"34c0b3bb2b1f828768fc0050881bdb1007f9505f6c2314a36ed5502efca2d04b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): src/Rask.Core/HtmlSerializer.cs:242-268 | src/Rask.Core/HtmlSerializer.cs:295-321 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/HtmlSerializer.cs:242\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/HtmlSerializer.cs"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"656ce5240022f79a0426c30d30dcf63d2f4168fb9c509ef4e1c9ec01678e91ba"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201326 lines \u00D7 3): src/Rask.Ui/UiFilter.cs:32-57 | src/Rask.Ui/UiFormField.cs:158-175 | src/Rask.Ui/UiMenuRadioGroup.cs:32-49 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiFilter.cs"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cb8249b5d32f5dd6a1e11fbd8d600da863238639a00faa8ab648575070aedd8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24\u201326 lines \u00D7 2): src/Rask.Wasm/WasmPrerender.cs:700-723 | src/Rask.Wasm/WasmPrerender.cs:778-803 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/WasmPrerender.cs"},"region":{"startLine":700}}}],"partialFingerprints":{"codehealthFindingId/v1":"855166740708150cb113af24728c03ac6edbeaf857ace539cac31a24f40e271b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24\u201325 lines \u00D7 2): src/Rask.Generators/ComponentFactoryGenerator.cs:5150-5174 | src/Rask.Generators/RoutesGenerator.cs:399-422 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":5150}}}],"partialFingerprints":{"codehealthFindingId/v1":"70602a2f154e268d68136553092be793caf70991e838d08e62305ae80d6861f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): src/Rask.Jobs/Job.cs:34-58 | src/Rask.Outbox/OutboxMessage.cs:45-69 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/Job.cs"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcabb0b1ae654b088df2976e2d83e2240e0680cbf915e75bbc8b91d245863b72"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201325 lines \u00D7 2): src/Rask.Server/RaskEndpointExtensions.cs:2576-2600 | src/Rask.Wasm/WasmLiveSession.cs:490-512 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Server/RaskEndpointExtensions.cs:2576\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2576}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d84de59ef9fe6f3ddb0ffedda7f07ca25bc80a54171d6d8e93371319903aaf8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201324 lines \u00D7 3): src/Rask.Generators/Blazor/BlazorGenerator.cs:319-342 | src/Rask.Generators/External/ExternalGenerator.cs:486-509 | src/Rask.Generators/Validation/ValidatorRegistryGenerator.cs:226-248 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Blazor/BlazorGenerator.cs"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"12d0e9e429e6302fc640094e93540e2b61cae9933bc35e538257da93ad8ed51f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): src/Rask.Core/Components/Input.cs:304-327 | src/Rask.Core/Components/Textarea.cs:146-169 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Input.cs:304\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Input.cs"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c515a34169496aab718efafcd6c99e2b9e5ca5f5848d3764fa6447a234552ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): src/Rask.Core/Live/LiveOptions.cs:180-203 | src/Rask.Spa.Hosting/SpaPath.cs:19-42 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LiveOptions.cs"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"df8895c8ef57c96edbf659ee8ce682daff839428dd7238b8b08de685eafe7741"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21\u201323 lines \u00D7 2): src/Rask.Api.Client/ApiCall.cs:253-273 | src/Rask.Cqrs.Client/RemoteDispatch.cs:592-614 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Api.Client/ApiCall.cs"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"684b7fe2fb3deaf694facd4526e354511764f7b92cad1bac2127e688952dd159"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): src/Rask.Core/Components/Svg/Line.cs:32-54 | src/Rask.Core/Components/Svg/LinearGradient.cs:44-66 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Svg/Line.cs:32\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/Line.cs"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fe1ccda184f3966ea1f568a28813c40fd4c37b266e668b1c6132201f659a547"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): src/Rask.Core/Components/Svg/LinearGradient.cs:63-85 | src/Rask.Core/Components/Svg/RadialGradient.cs:75-97 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Svg/LinearGradient.cs:63\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/LinearGradient.cs"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"c969c555883331a0083d228aebd97211d03c0fde994688bdd0c886b879291011"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): src/Rask.Dashboard/Pages/CachePage.cs:34-56 | src/Rask.Dashboard/Pages/StoragePage.cs:34-56 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Dashboard/Pages/CachePage.cs"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"a362ec160ed32fa6052a23f2efa6fe584194dca45fc5a1caff9a998052019c50"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 3): src/Rask.Jobs/JobOptions.cs:10-30 | src/Rask.Mail/MailOptions.cs:64-84 | src/Rask.Outbox/OutboxOptions.cs:7-35 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobOptions.cs\u0060 and \u0060src/Rask.Mail/MailOptions.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobOptions.cs"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f42a41ed57c84367e12b0df128375bc7d9345a88727822731a4a477fc291cde"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201321 lines \u00D7 2): src/Rask.Generators.Shared/WireShape.cs:538-558 | src/Rask.Generators.Shared/WireShape.cs:609-628 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/WireShape.cs"},"region":{"startLine":538}}}],"partialFingerprints":{"codehealthFindingId/v1":"318571a7e418e67013f1631703fc4de9431add6c92a15099cf2f5aa51ecfc18e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): src/Rask.Core/Components/Svg/Svg.cs:61-81 | src/Rask.Core/Components/Svg/Symbol.cs:48-68 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/Svg.cs"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fac5a77811a64a22b30aef7629be6de17c7cc042320bca73452677409967395"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): src/Rask.Core/Components/Svg/SvgText.cs:18-41 | src/Rask.Core/Components/Svg/Tspan.cs:15-35 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/SvgText.cs"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"b085370e7acbec9c9a8e805576f4f2437dba325b6038006283ec7864d63d42b6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): src/Rask.Core/ScopedCss/CssScoper.cs:219-239 | src/Rask.Core/ScopedCss/CssScoper.cs:258-278 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/ScopedCss/CssScoper.cs:219\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedCss/CssScoper.cs"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c93bd5af7003e15828161a6d6c8592c4c324c7a92669bd145e1f0c4bcca3c97"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): src/Rask.Server/RaskEndpointExtensions.cs:167-210 | src/Rask.Spa.Hosting/RaskSpaServiceCollectionExtensions.cs:66-85 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3c3d2dba1a047e3960135c130006c4032034787aef709b6d080f515ceab8f54"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): src/Rask.Ui/UiCheckbox.cs:21-40 | src/Rask.Ui/UiToggle.cs:20-41 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiCheckbox.cs:21\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiCheckbox.cs"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"772dbbdaf9e3624a80a9cfaf2b9734592e3baf9489f63ca069c2abbfdad0bafa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201320 lines \u00D7 2): src/Rask.Ui/UiCheckboxGroup.cs:22-38 | src/Rask.Ui/UiRadioGroup.cs:22-41 \u2014 before extracting anything, compare \u0060src/Rask.Ui/UiCheckboxGroup.cs\u0060 and \u0060src/Rask.Ui/UiRadioGroup.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 40 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiCheckboxGroup.cs:22\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiCheckboxGroup.cs"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"3366334089df80094630b067dbbc09f0639911d9ec7ccca8e638538ef33cefc0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 8): src/Rask.Core/Components/Svg/Filter.cs:43-61 | src/Rask.Core/Components/Svg/ForeignObject.cs:29-47 | src/Rask.Core/Components/Svg/Image.cs:35-53 | src/Rask.Core/Components/Svg/Mask.cs:48-66 | src/Rask.Core/Components/Svg/Pattern.cs:49-67 | src/Rask.Core/Components/Svg/Rect.cs:41-59 | src/Rask.Core/Components/Svg/Symbol.cs:58-76 | src/Rask.Core/Components/Svg/Use.cs:41-59 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 8 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/Filter.cs"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"db29f861514ff041bc37f9878eda6de49bed18c00df702827fa2513d2fef2e7c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 3): src/Rask.Jobs/JobProcessor.cs:136-154 | src/Rask.Mail/MailProcessor.cs:156-174 | src/Rask.Outbox/OutboxProcessor.cs:158-176 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobProcessor.cs\u0060 and \u0060src/Rask.Mail/MailProcessor.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Jobs/JobProcessor.cs:136\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060src/Rask.Jobs/JobProcessor.cs:135\u0060 calls \u0060EnqueueDueRecurringAsync\u0060, \u0060ConfigureAwait\u0060 and \u0060src/Rask.Mail/MailProcessor.cs:155\u0060 does not \u2014 after which the two agree again for 4 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobProcessor.cs"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4afe3ff6a5b4e81158f627b0e2d4dbc46037e41c6c5d4aa83fef5f63f4b048a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): src/Rask.Core/Components/A.cs:65-83 | src/Rask.Core/Components/Area.cs:67-85 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/A.cs"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7bd621fede1df40db311e40a41c9eda1390d459ef0a400d5c48ca882acbb284"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): src/Rask.Core/Components/Iframe.cs:87-105 | src/Rask.Core/Components/Img.cs:99-117 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Iframe.cs:87\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Iframe.cs"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"2715b1c1af5c16ca37226f4291884117026be2d6146e119d00c8055b42ba27d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201319 lines \u00D7 2): src/Rask.Logging/LogScopes.cs:86-104 | src/Rask.Logging/LogScopes.cs:106-122 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Logging/LogScopes.cs:86\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Logging/LogScopes.cs"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d74629bf7aa17d4d6fda9385d3a5c795e4a9cee781e6fe9c42685d1d1817bd4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): src/Rask.Server/RaskEndpointExtensions.cs:3041-3059 | src/Rask.Server/RaskEndpointExtensions.cs:3150-3168 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Server/RaskEndpointExtensions.cs:3041\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":3041}}}],"partialFingerprints":{"codehealthFindingId/v1":"a413de0a612151bdc18998cfd4bd9fa1253a6479a1512883b9ca1408a7094bde"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): src/Rask.Ui/UiDatePicker.cs:25-43 | src/Rask.Ui/UiDatePickerMultiple.cs:15-33 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiDatePicker.cs:25\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiDatePicker.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"c497ab8051c3aa8a8b749cea937856875bef9a42498f204669219431fc40d953"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 3): src/Rask.Core/Routing/RouteRegistry.cs:84-101 | src/Rask.Jobs/JobSerializerRegistry.cs:64-81 | src/Rask.Outbox/OutboxSerializerRegistry.cs:64-81 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobSerializerRegistry.cs\u0060 and \u0060src/Rask.Outbox/OutboxSerializerRegistry.cs\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 91 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Routing/RouteRegistry.cs:84\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060registrations\u0060 to \u0060IEnumerable\u003CRouteRegistration\u003E\u0060 in one and \u0060IEnumerable\u003C(string TypeName, Type Type)\u003E\u0060 in another, and the duplicated lines use it. The extracted unit therefore needs a parameter type that fits BOTH \u2014 their common supertype where they have one, or a new abstraction over them where they do not \u2014 and settling that is the step that comes BEFORE the extraction above. Where the two types are deliberately unrelated, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Routing/RouteRegistry.cs"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce3a6a6b4e94adc66cfe1d6ce55d68a952a7855667814b2d64c7e942301180a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201318 lines \u00D7 3): src/Rask.Generators/Analyzers/ComponentConstructionAnalyzer.cs:36-53 | src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs:47-61 | src/Rask.Generators/Analyzers/RedundantStateHasChangedAnalyzer.cs:44-58 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/Analyzers/ComponentConstructionAnalyzer.cs:36\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/ComponentConstructionAnalyzer.cs"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"799188484e348e381524cfcf4fa8c90689555893239906d6d46d9095b2d936d0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): src/Rask.Core/Components/Svg/Circle.cs:29-46 | src/Rask.Core/Components/Svg/RadialGradient.cs:46-63 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Svg/Circle.cs:29\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/Circle.cs"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"7355aad24ffc7a4cbf73c4639ad78d12a36a6a8ab3209c731ea48d4144601505"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): src/Rask.Core/Components/Svg/FeDropShadow.cs:35-52 | src/Rask.Core/Components/Svg/FeOffset.cs:26-43 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Svg/FeDropShadow.cs:35\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/FeDropShadow.cs"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c72a2c12ec25bd35327d67b0a4f69c63df6c4a1e4c62919533dca5a53dc2321"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): src/Rask.Postgres/RaskPostgresDbContextOptionsExtensions.cs:47-64 | src/Rask.SqlServer/RaskSqlServerDbContextOptionsExtensions.cs:47-64 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Postgres/RaskPostgresDbContextOptionsExtensions.cs:47\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Postgres/RaskPostgresDbContextOptionsExtensions.cs"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"233eb9f36941401eff348a6003b3d454411eb3e96153e1cd7856f4407c7b62aa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): src/Rask.Ui/UiFileInput.cs:92-110 | src/Rask.Ui/UiOtp.cs:57-74 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiFileInput.cs"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"df8ff0f2b7e3383e810b06c7c5aa7b4925db2d24c7fb14420e2f033d94d3229d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201318 lines \u00D7 2): src/Rask.Ui/UiMultiSelect.cs:499-515 | src/Rask.Ui/UiSelect.cs:439-456 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiMultiSelect.cs:499\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiMultiSelect.cs"},"region":{"startLine":499}}}],"partialFingerprints":{"codehealthFindingId/v1":"df277559d08ce36b4b70f18974f17e099f1d41f5d9f042155dbb5649b1088ec7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201317 lines \u00D7 2): src/Rask.Core/Live/LivePayload.cs:515-530 | src/Rask.Core/Live/LivePayload.cs:535-551 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Live/LivePayload.cs:515\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1d6f01c7e1ecd8c31728e8bcaee13923d34bd73c4b26d5267b47df86f394290"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201317 lines \u00D7 2): src/Rask.Generators/ComponentScopedCssGenerator.cs:52-62 | src/Rask.Generators/ComponentScopedJsGenerator.cs:103-119 \u2014 before extracting anything, compare \u0060src/Rask.Generators/ComponentScopedCssGenerator.cs\u0060 and \u0060src/Rask.Generators/ComponentScopedJsGenerator.cs\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedCssGenerator.cs"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"34731f63208f327f75e2d1b6bd8ead539174cdfa672a2e82974f149076e5aab3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): src/Rask.Jobs/JobSerializerRegistry.cs:13-29 | src/Rask.Outbox/OutboxSerializerRegistry.cs:13-29 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobSerializerRegistry.cs\u0060 and \u0060src/Rask.Outbox/OutboxSerializerRegistry.cs\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 91 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Jobs/JobSerializerRegistry.cs:13\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobSerializerRegistry.cs"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"1aa6f24e0bfe412bc6641f18bce0e2dc13f7c6c625ef735f2918e692aa2b2540"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): src/Rask.Jobs/JobSerializerRegistry.cs:94-110 | src/Rask.Outbox/OutboxSerializerRegistry.cs:94-110 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobSerializerRegistry.cs\u0060 and \u0060src/Rask.Outbox/OutboxSerializerRegistry.cs\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 91 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobSerializerRegistry.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca334adb6aaf855a8c5695b3e7ea9131c0916ebd1e8c45a2abf20d3a59c761ba"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 4): src/Rask.Ui/UiCheckbox.cs:40-71 | src/Rask.Ui/UiMenuCheckbox.cs:34-49 | src/Rask.Ui/UiRadio.cs:38-63 | src/Rask.Ui/UiToggle.cs:34-55 \u2014 before extracting anything, compare \u0060src/Rask.Ui/UiRadio.cs\u0060 and \u0060src/Rask.Ui/UiToggle.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 90 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiCheckbox.cs"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5963883a90c0392883d0bf7d37924b8e541b0fa2d4ee66da4c8cf97cd61ae95"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201316 lines \u00D7 2): src/Rask.Batteries.Generators/ModelInputGenerator.cs:160-171 | src/Rask.Batteries.Generators/ModelRegistryGenerator.cs:89-104 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Batteries.Generators/ModelInputGenerator.cs:160\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060src/Rask.Batteries.Generators/ModelRegistryGenerator.cs:109\u0060 calls \u0060EmitConventions\u0060 and \u0060src/Rask.Batteries.Generators/ModelInputGenerator.cs:172\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2b0721499e1a389eb24c4f2565fe0e8367b7ff0b7e3daa40bd2a6f0014aa090"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 2): src/Rask.Core/Live/EventPayload.cs:23-38 | src/Rask.Core/Live/ScrollEvent.cs:23-37 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Each matched range is the entire body of the declaration above it, so the region is already a complete unit: move that whole declaration to the shared location and have each site call it, rather than lifting the lines out of their bodies. Any \u0060return\u0060 inside it is the body\u0027s own exit and keeps its meaning in the moved unit."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/EventPayload.cs"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"c748eecc2d0462b2e6eb8774139812ea5b1315abc97b36ce86bef9c4d791af06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): src/Rask.Generators/ComponentFactoryGenerator.cs:2326-2341 | src/Rask.Generators/ComponentFactoryGenerator.cs:2843-2858 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:2326\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":2326}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e9c670e18bfefa2c63447a99e12721e41295ca872343ad8a76db5852fc7eb9d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): src/Rask.Generators/Translations/MessageParser.cs:198-213 | src/Rask.Generators/Translations/TranslationCatalogGenerator.cs:838-853 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/MessageParser.cs"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd0872108fb92ec985346e1a3af125641855f4b53177dd01f3d75122b4aa7fd7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): src/Rask.Jobs/JobMetrics.cs:44-59 | src/Rask.Outbox/OutboxMetrics.cs:44-59 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Jobs/JobMetrics.cs:44\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobMetrics.cs"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b6f0f3180e48576c25a73daf34578ff5e0362da7873fa8a8173004ad7e8a49b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): src/Rask.External.Tasks/ExternalBuildPlan.cs:747-761 | src/Rask.Spa.Tasks/GeneratedTypeScript.cs:117-131 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalBuildPlan.cs"},"region":{"startLine":747}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bc4fc58eecbd7ca854679b08875010fba84002502fc444675f45a22eda5fb68"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): src/Rask.Server/RaskEndpointExtensions.cs:2447-2461 | src/Rask.Wasm/WasmLiveSession.cs:365-379 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Server/RaskEndpointExtensions.cs:2447\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2447}}}],"partialFingerprints":{"codehealthFindingId/v1":"2647b1160fc543853308c0c102d422d165cbb9783ebe643682c234c10398b1e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): src/Rask.Generators/External/ExternalGenerator.cs:334-347 | src/Rask.Generators/External/ExternalGenerator.cs:379-392 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/External/ExternalGenerator.cs:334\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"6902bf70486283a17c048233e1481e5d2c43dd2fcb582a34471edc0fc3b6f756"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): src/Rask.Ui/UiMultiSelect.cs:475-488 | src/Rask.Ui/UiSelect.cs:415-428 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiMultiSelect.cs"},"region":{"startLine":475}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fb53344099cf3d265abd9b3bee39b25210044ba37724ab14b90c96def57c2eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): src/Rask.Generators/ComponentScopedCssGenerator.cs:129-141 | src/Rask.Generators/ComponentScopedJsGenerator.cs:235-247 \u2014 before extracting anything, compare \u0060src/Rask.Generators/ComponentScopedCssGenerator.cs\u0060 and \u0060src/Rask.Generators/ComponentScopedJsGenerator.cs\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedCssGenerator.cs"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"148091b85a37527f0113efade5a8c864180f20b29f6ce89ea11bee7b07e4593c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): src/Rask.Jobs/JobMetrics.cs:24-36 | src/Rask.Outbox/OutboxMetrics.cs:24-36 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobMetrics.cs"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b928f00f9b9dceabe2481a6a41fc91b18bfd80031b00d52bff352482da78be4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201312 lines \u00D7 3): src/Rask.Site/Features/Validation/InlineAsyncValidateDemo.cs:19-27 | src/Rask.Site/Features/Validation/InlineValidateDemo.cs:14-25 | src/Rask.Site/Features/Validation/ValidatableObjectDemo.cs:20-28 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060src/Rask.Site/Features/Validation/InlineValidateDemo.cs:10\u0060 calls \u0060FieldError\u0060, \u0060Select\u0060, \u0060Key\u0060 and \u0060src/Rask.Site/Features/Validation/InlineAsyncValidateDemo.cs:16\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Validation/InlineAsyncValidateDemo.cs"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"9124a23c8513999cce55e46956f520deba2c5666d82aaba64b7a4f3edfd36e04"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/Rask.Generators.Shared/WireShape.cs:472-483 | src/Rask.Generators.Shared/WireShape.cs:579-590 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators.Shared/WireShape.cs:472\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/WireShape.cs"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ed4cf19f54c0bddf6d00b31de349d549a549a66f86a4adde77ddea540cbcf28"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/Rask.Core/Components/Input.cs:497-508 | src/Rask.Core/Components/Textarea.cs:222-233 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Textarea.cs:222\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Input.cs"},"region":{"startLine":497}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8377d77a468cfbb8f8edd3ce770322d950997b220213a6a1f0d4780c5389c68"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/Rask.Ui/UiCheckboxGroup.cs:138-149 | src/Rask.Ui/UiRadioGroup.cs:105-116 \u2014 before extracting anything, compare \u0060src/Rask.Ui/UiCheckboxGroup.cs\u0060 and \u0060src/Rask.Ui/UiRadioGroup.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 40 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiCheckboxGroup.cs:138\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiCheckboxGroup.cs"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"6580755c720217dba7184bcd5cc6b4f82d74ab3ee4e1ac7f06aac433f7ce0051"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/Rask.Ui/UiInput.cs:202-213 | src/Rask.Ui/UiInput.cs:222-233 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiInput.cs:202\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiInput.cs"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e274b8848fb84181d5701f9ec2fd7ebc210e11ce7765c2954f6229848c061f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/Rask.Ui/UiOtp.cs:92-103 | src/Rask.Ui/UiOtp.cs:109-120 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiOtp.cs:92\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiOtp.cs"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffd98c50dc80cb2339fbb4acba422b867fde03711f64a64e83f8aec8b21dd5e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Batteries.Generators/EquatableArray.cs:24-34 | src/Rask.Generators/ComponentFactoryGenerator.cs:5887-5897 \u2014 before extracting anything, compare \u0060src/Rask.Batteries.Generators/EquatableArray.cs\u0060 and \u0060src/Rask.Generators/ComponentFactoryGenerator.cs\u0060 as WHOLE FILES: 85% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Batteries.Generators/EquatableArray.cs:24\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/EquatableArray.cs"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddad89541665f3dd73ec987d8aeca1654a40818f6a43de32541cbb5532f7d776"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Batteries.Generators/ModelInputGenerator.cs:899-909 | src/Rask.Batteries.Generators/ModelInputGenerator.cs:942-952 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060src/Rask.Batteries.Generators/ModelInputGenerator.cs:954\u0060 calls \u0060AppendLine\u0060 and \u0060src/Rask.Batteries.Generators/ModelInputGenerator.cs:911\u0060 does not \u2014 after which the two agree again for 3 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":899}}}],"partialFingerprints":{"codehealthFindingId/v1":"a298f384fe7c50dc84ae3055bbee819acfc43d258dcfc9b8d97b09541c42b18e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Batteries.Generators/ModelInputGenerator.cs:984-994 | src/Rask.Batteries.Generators/ModelInputGenerator.cs:1016-1026 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":984}}}],"partialFingerprints":{"codehealthFindingId/v1":"934f8095aae7d019eeb886379ab3c0ade42d68e552a0a056db1d0390a06d869e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Core/Components/Select.cs:224-234 | src/Rask.Core/Components/Textarea.cs:114-125 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Components/Select.cs:224\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Select.cs"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a615c9c8fadd227e3a098e32e4a658dd65f24c4575a34371e2e9b43e7cf8155"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Core/Live/FrameDiffer.cs:882-892 | src/Rask.Core/Live/FrameDiffer.cs:1064-1074 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Core/Live/FrameDiffer.cs:1064\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":882}}}],"partialFingerprints":{"codehealthFindingId/v1":"095843c9a4861561979060f6e99d9d0aa5ced346611f2c604526e946557c673e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201311 lines \u00D7 2): src/Rask.Server/RaskEndpointExtensions.cs:1156-1166 | src/Rask.Server/RaskEndpointExtensions.cs:1323-1331 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Server/RaskEndpointExtensions.cs:1156\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1156}}}],"partialFingerprints":{"codehealthFindingId/v1":"85c18753a123ac0f7d76cbecebce8d095aba21fb45455f1c1224544f62402369"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): src/Rask.External.Tasks/ExternalIslandMetadata.cs:44-54 | src/Rask.External.Tasks/ExternalIslandMetadata.cs:70-79 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.External.Tasks/ExternalIslandMetadata.cs:44\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalIslandMetadata.cs"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"44ddf36c5b4f4a3261d56369479c464c79af4091112deca5b11c1abd2ae5e067"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u201310 lines \u00D7 2): src/Rask.Ui/UiMultiSelect.cs:244-250 | src/Rask.Ui/UiSelect.cs:266-275 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Ui/UiSelect.cs:266\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiMultiSelect.cs"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"899239c80a41e05948ce3b94481e0f6747620f218532537b64f1f9ecd1cd7fe5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): src/Rask.Ui/UiRadioGroup.cs:47-56 | src/Rask.Ui/UiSelect.cs:255-264 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiRadioGroup.cs"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a6e8cde3ba81f29859c1d0b91b5394d7f0e0263754cd3ad38bf6688f0d88e4b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): src/Rask.External.Tasks/ExternalPackageScan.cs:187-196 | src/Rask.External.Tasks/ExternalPackageScan.cs:198-206 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.External.Tasks/ExternalPackageScan.cs:187\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageScan.cs"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"3441af659806390012f4f96cd5e78f95057ed78f6d33e7e0a38d7749173b18b6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): src/Rask.Generators/ComponentFactoryGenerator.cs:142-150 | src/Rask.Generators/RoutesGenerator.cs:201-211 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:142\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e43d17b30f808874015a0da2137090f536f0ace2ee2ee4faf5109a8821164d3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/Rask.Auth.Api/AccountService.cs:344-351 | src/Rask.Auth.Api/AccountService.cs:378-385 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Auth.Api/AccountService.cs:344\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Auth.Api/AccountService.cs"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"a880756755141da6a1279c4f133faf630934e6d007fff74573fd7f677d5d58c6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/Rask.Batteries.Generators/ModelInputGenerator.cs:1238-1245 | src/Rask.Batteries.Generators/ModelInputGenerator.cs:1249-1256 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Batteries.Generators/ModelInputGenerator.cs:1238\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":1238}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef8b8018abe440a1e0bead420988896026d20b6de524ce811fbf790261a339c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): src/Rask.Ui/UiCheckboxGroup.cs:123-130 | src/Rask.Ui/UiRadioGroup.cs:87-94 \u2014 before extracting anything, compare \u0060src/Rask.Ui/UiCheckboxGroup.cs\u0060 and \u0060src/Rask.Ui/UiRadioGroup.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 40 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060src/Rask.Ui/UiRadioGroup.cs:95\u0060 calls \u0060Name\u0060 and \u0060src/Rask.Ui/UiCheckboxGroup.cs:131\u0060 does not \u2014 after which the two agree again for 4 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiCheckboxGroup.cs"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"c25031e42ff1a2641a5fd8b07e9bb2ea4d80ceb5799028573a00e7e4eed2b09d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): src/Rask.Dashboard/Pages/CachePage.cs:42-48 | src/Rask.Dashboard/Pages/QueuePage.cs:56-62 | src/Rask.Dashboard/Pages/StoragePage.cs:42-48 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Dashboard/Pages/CachePage.cs:42\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Dashboard/Pages/CachePage.cs"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"67a5e8eeadbb5ce82aa99a0026349ebb2dc98ebd9935fbaf714eec8bd2b163bd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): src/Rask.Batteries.Generators/AuthUserGenerator.cs:44-50 | src/Rask.Batteries.Generators/ModelRegistryGenerator.cs:85-91 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Batteries.Generators/AuthUserGenerator.cs:44\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/AuthUserGenerator.cs"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f0097192ee72b780d5bb03e75849b07787343066345dbe15925f89824d79e32"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): src/Rask.Generators/ComponentFactoryGenerator.cs:1774-1780 | src/Rask.Generators/ComponentFactoryGenerator.cs:3664-3671 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:1774\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:1781\u0060 calls \u0060AddSource\u0060, \u0060From\u0060, \u0060ToString\u0060 and \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:3672\u0060 does not \u2014 after which the two agree again for 3 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":1774}}}],"partialFingerprints":{"codehealthFindingId/v1":"0be4477f73b532dc437ef6d16fc6ed7b772eeb62587f15c6e568a149e04b2c9d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): src/Rask.Jobs/Job.cs:110-117 | src/Rask.Outbox/OutboxMessage.cs:116-122 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060entity\u0060 to \u0060EntityTypeBuilder\u003CJob\u003E\u0060 in one and \u0060EntityTypeBuilder\u003COutboxMessage\u003E\u0060 in another, and the duplicated lines use it. The extracted unit therefore needs a parameter type that fits BOTH \u2014 their common supertype where they have one, or a new abstraction over them where they do not \u2014 and settling that is the step that comes BEFORE the extraction above. Where the two types are deliberately unrelated, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060src/Rask.Jobs/Job.cs:109\u0060 calls \u0060ThrowIfNull\u0060 and \u0060src/Rask.Outbox/OutboxMessage.cs:115\u0060 does not \u2014 after which the two agree again for 4 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/Job.cs"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"1768fe50896e78174e47ca0902debb82eca9b1e4f39d0806a57ec0268277e165"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): src/Rask.Generators/ComponentFactoryGenerator.cs:139-144 | src/Rask.Generators/ComponentScopedCssGenerator.cs:51-57 | src/Rask.Generators/ComponentScopedJsGenerator.cs:102-108 \u2014 before extracting anything, compare \u0060src/Rask.Generators/ComponentScopedCssGenerator.cs\u0060 and \u0060src/Rask.Generators/ComponentScopedJsGenerator.cs\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:139\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5bfa2591fcaf96cd97b87c7af5610cf1ff312033337011529bfd011e69491a1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): src/Rask.Generators/ComponentFactoryGenerator.cs:1764-1769 | src/Rask.Generators/ComponentFactoryGenerator.cs:1772-1777 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":1764}}}],"partialFingerprints":{"codehealthFindingId/v1":"80ac29fc2da913bfd434b8eff7b5bd7f8bd5497a6f71494742893d5cc3da6303"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): src/Rask.Site/Features/ErrorBoundary/BoomHandlerDemo.cs:19-24 | src/Rask.Site/Features/ErrorBoundary/BoomRenderDemo.cs:49-54 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/ErrorBoundary/BoomHandlerDemo.cs"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"afbc6d2c14e07d4711904b81d96722ba016ef4789cab2853784e4f6d33b14b95"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): src/Rask.Generators/ComponentFactoryGenerator.cs:1765-1769 | src/Rask.Generators/ComponentFactoryGenerator.cs:1773-1777 | src/Rask.Generators/ComponentFactoryGenerator.cs:3663-3668 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:1765\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":1765}}}],"partialFingerprints":{"codehealthFindingId/v1":"a24b7fb1f3589255fef5520602d1c9ba202c498029568465916467d1206af50b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): src/Rask.DevTools/Panel/DevToolsPerfTab.cs:221-225 | src/Rask.DevTools/Panel/DevToolsWireTab.cs:123-127 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.DevTools/Panel/DevToolsPerfTab.cs:221\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Panel/DevToolsPerfTab.cs"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3d4dc5311f19d12f5e1756c98a8eacc5cb11473f8fad21763246cca89bd5564"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): src/Rask.Generators/ComponentFactoryGenerator.cs:1187-1191 | src/Rask.Generators/ComponentFactoryGenerator.cs:1201-1205 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060src/Rask.Generators/ComponentFactoryGenerator.cs:1187\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":1187}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcc56b2c3c738d409ae8030a779107560831d8714d04137d947171f1c4b600d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5): src/Rask.Site/Features/UiKit/UiKitDataDisplayDemo.cs:172-191 | src/Rask.Site/Features/UiKit/UiKitDataGridDemo.cs:145-152 | src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs:390-411 | src/Rask.Site/Features/UiKit/UiKitFeedbackDemo.cs:135-157 | src/Rask.Site/Features/UiKit/UiKitLayoutDemo.cs:152-159 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 5 call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060src/Rask.Site/Features/UiKit/UiKitDataDisplayDemo.cs:170\u0060 calls \u0060Month\u0060 and \u0060src/Rask.Site/Features/UiKit/UiKitDataGridDemo.cs:143\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitDataDisplayDemo.cs"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"b98f0b6f8ceee897a99f09f9a9aa88266205d94f9ef6cadc3d18c3337e5e5004"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): src/Rask.Generators.Shared/AggregateShape.cs:176-180 | src/Rask.Generators.Shared/GeneratedModelShape.cs:934-938 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/AggregateShape.cs"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"99a38239f1b335a951e0a2ab2c2c0c1e523073bb2657146eddbd16dd4256e40a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Generators.Shared/AggregateShape.cs:160-170 | src/Rask.Generators.Shared/GeneratedModelShape.cs:941-951 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/AggregateShape.cs"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"765d1f83bb76fc37d8b948ae110f4a8fb713422d3fdfd7c41a63b50023d7543a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): src/Rask.Batteries.Generators/EquatableArray.cs:45-57 | src/Rask.Generators/ComponentFactoryGenerator.cs:5908-5920 \u2014 before extracting anything, compare \u0060src/Rask.Batteries.Generators/EquatableArray.cs\u0060 and \u0060src/Rask.Generators/ComponentFactoryGenerator.cs\u0060 as WHOLE FILES: 85% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/EquatableArray.cs"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9ae7e005cbc54c3fa8369ebfcd2c49746320658875f72db05017218565fbf58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Generators.Shared/SymbolRegistration.cs:212-222 | src/Rask.Generators/ComponentFactoryGenerator.cs:4607-4617 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/SymbolRegistration.cs"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9a8d5cdbc4fef00f9ca6ddf24dbbf9bbaef473015b421c6f5fc54e896128b61"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/Rask.Core/Components/Base.cs:22-33 | src/Rask.Core/Components/Svg/SvgA.cs:23-34 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Base.cs"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"aec1c6ef5375a445b9825013f4780b0e773f3d1a7d84daa023f927f025879047"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): src/Rask.Core/Components/DefaultNotFoundPage.cs:19-29 | src/Rask.Core/Components/NavLink.cs:52-63 | src/Rask.Core/Routing/Outlet.cs:24-35 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/DefaultNotFoundPage.cs"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec0de75fc0f2362b4f2c00047cb6faaf4f7d42b1347c168356c8b65679465a31"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): src/Rask.Core/Components/Svg/Polygon.cs:22-33 | src/Rask.Core/Components/Svg/Polyline.cs:23-34 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/Polygon.cs"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"a00c799fa5a63401113ccee247a897605f971b6ae9602c313d4110a5861d6cae"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): src/Rask.DevTools/Panel/DevToolsErrorsTab.cs:52-58 | src/Rask.DevTools/Panel/DevToolsTabs.cs:64-70 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Panel/DevToolsErrorsTab.cs"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d23adc46faaf86d768a726a7f0195d7cd1f41e0e1cae89e0f701919f5417cb9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): src/Rask.DevTools/Panel/DevToolsErrorsTab.cs:62-75 | src/Rask.DevTools/Panel/DevToolsTabs.cs:74-86 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Panel/DevToolsErrorsTab.cs"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8191ba7b41fb231278ba75c4c51c3a55f7fe25dad8c8f93868797f5e7ac8e58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): src/Rask.External.Tasks/ExternalPackageSpecifier.cs:42-47 | src/Rask.Generators/External/PackageIslands/PackageIslandProps.cs:165-170 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/ExternalPackageSpecifier.cs"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9263f7b9eb9e5bf8d81d605d5de0f01fa41aebbd36314446d8ea15387df02af"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5): src/Rask.Generators/Analyzers/ChainAssignedAfterwardsAnalyzer.cs:170-179 | src/Rask.Generators/Analyzers/DuplicateChainCallAnalyzer.cs:110-117 | src/Rask.Generators/Analyzers/GridColumnTokenAnalyzer.cs:250-259 | src/Rask.Generators/Analyzers/KeyOpensChainAnalyzer.cs:140-147 | src/Rask.Generators/Analyzers/OptionTemplateNativeAnalyzer.cs:136-145 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 5 call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060operation\u0060 to \u0060IOperation?\u0060 in one and \u0060IInvocationOperation\u0060 in another, and the duplicated lines use it. The extracted unit therefore needs a parameter type that fits BOTH \u2014 their common supertype where they have one, or a new abstraction over them where they do not \u2014 and settling that is the step that comes BEFORE the extraction above. Where the two types are deliberately unrelated, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060src/Rask.Generators/Analyzers/DuplicateChainCallAnalyzer.cs:105\u0060 calls \u0060Unwrap\u0060 and \u0060src/Rask.Generators/Analyzers/ChainAssignedAfterwardsAnalyzer.cs:166\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/ChainAssignedAfterwardsAnalyzer.cs"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b62850635c898002284e23344448b04afe4f9034d7b92bd09a2e63afc72fe7b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): src/Rask.Generators/Analyzers/DuplicateChainCallAnalyzer.cs:99-106 | src/Rask.Generators/Analyzers/GridColumnTokenAnalyzer.cs:238-245 | src/Rask.Generators/Analyzers/OptionTemplateNativeAnalyzer.cs:124-131 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/DuplicateChainCallAnalyzer.cs"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"f981c4e1af4a03859f9b9375009158f7e3172807057f6d3edb72ee5e0b4d3185"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs:167-177 | src/Rask.Generators/Analyzers/RedundantStateHasChangedAnalyzer.cs:175-185 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f3672c9e0bd4304435c3fbeb0272983464c6716f3819ded90eb168793bed6a8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): src/Rask.Generators/ComponentScopedCssGenerator.cs:104-114 | src/Rask.Generators/ComponentScopedJsGenerator.cs:180-190 | src/Rask.Generators/RoutesGenerator.cs:382-392 \u2014 before extracting anything, compare \u0060src/Rask.Generators/ComponentScopedCssGenerator.cs\u0060 and \u0060src/Rask.Generators/ComponentScopedJsGenerator.cs\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedCssGenerator.cs"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"9151d952634ccea7193a4b1e17f669ba0eb3c72117cf7ebc23a28a1771d168fe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): src/Rask.Generators/ComponentScopedCssGenerator.cs:233-248 | src/Rask.Generators/ComponentScopedJsGenerator.cs:462-477 \u2014 before extracting anything, compare \u0060src/Rask.Generators/ComponentScopedCssGenerator.cs\u0060 and \u0060src/Rask.Generators/ComponentScopedJsGenerator.cs\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 93 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedCssGenerator.cs"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"48f02d5c5eb40aeb6822030debfcc5713d29b2bcd1023bfc85b2e50fa1f56c78"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): src/Rask.Jobs/JobOptions.cs:152-162 | src/Rask.Mail/MailOptions.cs:198-208 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobOptions.cs\u0060 and \u0060src/Rask.Mail/MailOptions.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobOptions.cs"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2052e9d26f7f7f82c9734a7d1e5ddbd7cd43baef512719371ca763ee8a24272"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 3): src/Rask.Jobs/JobProcessor.cs:115-129 | src/Rask.Mail/MailProcessor.cs:136-150 | src/Rask.Outbox/OutboxProcessor.cs:132-146 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobProcessor.cs\u0060 and \u0060src/Rask.Mail/MailProcessor.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobProcessor.cs"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"45e6d903612e666f0378ba5a70a90971d9328d39adce1fd400e9f0f29ebbec09"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): src/Rask.Jobs/JobSerializerRegistry.cs:33-41 | src/Rask.Outbox/OutboxSerializerRegistry.cs:33-41 \u2014 before extracting anything, compare \u0060src/Rask.Jobs/JobSerializerRegistry.cs\u0060 and \u0060src/Rask.Outbox/OutboxSerializerRegistry.cs\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 91 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/JobSerializerRegistry.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"45336e1309a3f180dcc72cf369face1857c9e61a37dfae4a1b4e6600e8029969"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): src/Rask.Mail/MailProcessor.cs:395-411 | src/Rask.Outbox/OutboxProcessor.cs:401-417 \u2014 before extracting anything, compare \u0060src/Rask.Mail/MailProcessor.cs\u0060 and \u0060src/Rask.Outbox/OutboxProcessor.cs\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 136 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Mail/MailProcessor.cs"},"region":{"startLine":395}}}],"partialFingerprints":{"codehealthFindingId/v1":"650dc8a4f1a42b2e10e8e174fc2ad7f2419fe2bf21680a9a45a93b4fd0c2054d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): src/Rask.Meta.Hosting/NodeSupervisor.cs:276-285 | src/Rask.Spa.Hosting/SpaDevServer.cs:135-144 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Meta.Hosting/NodeSupervisor.cs"},"region":{"startLine":276}}}],"partialFingerprints":{"codehealthFindingId/v1":"53da0c3a398562b97f2d54412c93ca4a5b83f3a89e459eb03e1982621a4b781e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): src/Rask.Server/Diagnostics/RaskServerDiagnostics.cs:69-87 | src/Rask.Wasm/Diagnostics/RaskWasmDiagnostics.cs:65-81 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Diagnostics/RaskServerDiagnostics.cs"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea778b99fb88d0c50ca151229ae57db1ac7c672efca03bf1a3b8dfd746a19de7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): src/Rask.Site/Features/Virtualize/VirtualizeItemsDemo.cs:73-77 | src/Rask.Site/Features/Virtualize/VirtualizeProviderDemo.cs:80-84 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Virtualize/VirtualizeItemsDemo.cs"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc29177c5818d4eb3482b64d7d27c8ee0d39a2fca639b3e7972590296b61ccac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): src/Rask.SQLite.EntityFrameworkCore/RaskSqliteRangeExclusionSqlGenerator.cs:38-43 | src/Rask.SQLite.EntityFrameworkCore/RaskSqliteStrictRangeExclusionSqlGenerator.cs:33-38 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite.EntityFrameworkCore/RaskSqliteRangeExclusionSqlGenerator.cs"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c1aef897d29ce67d8a3549fb1952a248bb4db14d2f6abaf75daa7016ad8e6e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): src/Rask.SQLite.Litestream/LitestreamServiceCollectionExtensions.cs:63-79 | src/Rask.SQLite.Snapshots/SqliteSnapshotsServiceCollectionExtensions.cs:67-83 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite.Litestream/LitestreamServiceCollectionExtensions.cs"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"78f590cd93bab7ce1882601e14ac2a4b7c25882ac7e123657926e82444130fc8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): src/Rask.Ui/UiMultiSelect.cs:692-697 | src/Rask.Ui/UiSelect.cs:662-667 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiMultiSelect.cs"},"region":{"startLine":692}}}],"partialFingerprints":{"codehealthFindingId/v1":"a938125166bd15c639a43c1612de299d6768f6567a622217a71d4415b5812766"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Api(net10.0): Rask.Api(net10.0): abstractness 0.00, instability 0.00, distance 1.00 \u2014 zone of pain \u2014 concrete and depended on by 1 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0f5c5a64e43b2cd53b97ea60ba7db57b06fed7a8669388e8597b4193e2c468b0"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Postgres(net10.0): Rask.Postgres(net10.0): abstractness 0.00, instability 0.00, distance 1.00 \u2014 zone of pain \u2014 concrete and depended on by 1 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a477f52bb29ba09c4148cdd023ea675f2e86005bd7f895eaa80169cc18f03f5b"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.SqlServer(net10.0): Rask.SqlServer(net10.0): abstractness 0.00, instability 0.00, distance 1.00 \u2014 zone of pain \u2014 concrete and depended on by 1 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f3a9690f233f4fa26e2447b75f8acae275bc23b5243b4fc4bc83fd8cee7e67a2"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.WebPush(net10.0): Rask.WebPush(net10.0): abstractness 0.05, instability 0.00, distance 0.95 \u2014 zone of pain \u2014 concrete and depended on by 1 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8d6411a66c79bf52074cbb8b31b79ec32b4e780333b9584f75a14662b33815cf"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Wire(net10.0): Rask.Wire(net10.0): abstractness 0.05, instability 0.00, distance 0.95 \u2014 zone of pain \u2014 concrete and depended on by 6 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5a39cd2763af09eb39e0018927aa7b4f3def93188c642bc0f789b194c37051b0"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.SQLite(net10.0): Rask.SQLite(net10.0): abstractness 0.07, instability 0.00, distance 0.93 \u2014 zone of pain \u2014 concrete and depended on by 3 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cc3180d94fba06a0dd73657a1b0c15e9d5d2ac991980a9d92e6cfe7ceffe9ea6"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Ui(net10.0): Rask.Ui(net10.0): abstractness 0.04, instability 0.08, distance 0.88 \u2014 zone of pain \u2014 concrete and depended on by 4 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"de2224e7a7e6b159a51eb45abad15118cde47462cd80033f0d593a3a58909f8e"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.SQLite.Snapshots(net10.0): Rask.SQLite.Snapshots(net10.0): abstractness 0.17, instability 0.00, distance 0.83 \u2014 zone of pain \u2014 concrete and depended on by 2 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"50b23fe9f083e45fe863d9592e90f4ad60d08fdb1301e2ceb81aebe2410e44c5"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Validation.FluentValidation(net10.0): Rask.Validation.FluentValidation(net10.0): abstractness 0.00, instability 0.17, distance 0.83 \u2014 zone of pain \u2014 concrete and depended on by 2 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"3a94076acd815eb517c2507fd18c10b2368f7c235d28da2664722ac97b14f725"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Core(net10.0): Rask.Core(net10.0): abstractness 0.16, instability 0.02, distance 0.82 \u2014 zone of pain \u2014 concrete and depended on by 18 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a4f886ee01cb3bcbaae9ff7b96bf1c92e090a3fa25fa58193a3b171501f6d211"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Api.Client(net10.0): Rask.Api.Client(net10.0): abstractness 0.00, instability 0.20, distance 0.80 \u2014 zone of pain \u2014 concrete and depended on by 1 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"2934e3376a2ab4140ce478fe196a37445a93453804cc258c7c71cff104918ed6"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Data(net10.0): Rask.Data(net10.0): abstractness 0.18, instability 0.06, distance 0.76 \u2014 zone of pain \u2014 concrete and depended on by 8 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e394fcf4d928e6e42600405f42ef3e036e06dee5dc18cecd09056a69df813158"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Server(net10.0): Rask.Server(net10.0): abstractness 0.05, instability 0.20, distance 0.75 \u2014 zone of pain \u2014 concrete and depended on by 2 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f1e664237673b771bb8033bbc3fec27d65316c0cfeaccc244502367d1b14c48a"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Logging(net10.0): Rask.Logging(net10.0): abstractness 0.07, instability 0.20, distance 0.73 \u2014 zone of pain \u2014 concrete and depended on by 2 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"93eda97592fefb0ef5415f05b966be4310de0e50d54532faa103e3f39f731751"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Rask.Storage(net10.0): Rask.Storage(net10.0): abstractness 0.08, instability 0.20, distance 0.72 \u2014 zone of pain \u2014 concrete and depended on by 2 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"4c1126424a5006f4eac5d10732f6e7e5f71e745edc5966614e35f99a54f08135"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: LiveRenderContext (LCOM4 5): LiveRenderContext\u0027s methods fall into 5 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 5 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LiveRenderContext.cs"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"5393a6f92bfca35999793f392302cf42eb5ae59e1e42867baf3e1774664b91b3"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: Component (LCOM4 4): Component\u0027s methods fall into 4 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 4 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb588edc32bd316108c0f6018c4109026e99b6a2d793520b06fe524fa59fd8bc"}},{"ruleId":"D8","level":"warning","message":{"text":"Coverage not measured \u2014 .NET and JavaScript/TypeScript suite: Coverage NOT MEASURED: the .NET half could not be measured \u2014 no coverage produced (collector absent, or test run exceeded the inline budget); the JavaScript/TypeScript half could not be measured \u2014 src/Rask.Templates/analog/client/ runs vitest but declares no coverage provider, so the suite can run and still produce no lcov \u2014 add \u0060@vitest/coverage-v8\u0060 (or \u0060@vitest/coverage-istanbul\u0060) as a devDependency. This repository\u0027s production source spans both ecosystems, and no partial figure is published as if it were the whole: coverage is excluded from the score rather than counted as a near-zero. The named suite step is one the repository\u0027s maintainers can perform; once it passes, the real number is measured on the next scan. Alternatively, commit the lcov/Cobertura report your CI produces and it is read without a re-run."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"62e63e619c28f057e129f2997c965d32a457366a9ce18ca019ffb6bdfba85c99"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: WithName_decides_the_client_method_name: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Api.Client.Tests/MinimalApiRoundTripTests.cs"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bfa59d60c7d3be7db156aa04f1a627c5fceb4870fa7d9e53bbb4328294aa0b4"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Changed_DoesNotThrowWhenSubscribedAndUnsubscribed: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Authentication/AnonymousUserProviderTests.cs"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"d683b03448bfcdf38dab43e84bb2d380cf89e6609ec3b5dd639f71799b18844e"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: MessagesForAnUnknownConnectionAreIgnored: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Browser/SignalingTests.cs"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d837b52383f24c0060f8d9f232401d8a63c44b261c2226298c177b67509272f"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Pushes_ForAnUnknownIdAreIgnored: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Browser/WebRtcTests.cs"},"region":{"startLine":484}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3b2d26b948ce1d93cfc9037b499dd26da8c798516afea3cf3739b434c99a029"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Report_NullSink_IsNoOp: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Diagnostics/RaskDiagnosticsTests.cs"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"907da2969312b8b0be89a14d2a3c2a31e0e3cd4da51cc2e649467aff9ef0b98f"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: NotifyAndValidateFieldAsync_NullContext_IsNoOp: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Forms/PublicBindingApiTests.cs"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"c469cfe2eadceff2a872018ce5c336c63e3d30ec3954e68925783f12bfda3951"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Changed_UnknownId_IsNoOp: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Interop/BatteryTests.cs"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2b14a993e4b9f32de7f68cf84fd41184c95282a0e69cb2bab0b08856b8595d4"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Receive_UnknownId_IsNoOp: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Interop/BroadcastChannelTests.cs"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"78d17e9c9debaeeca54f0a29ee059808e777137fafe64ba4150ee51bd3edc778"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Result_UnknownId_IsNoOp: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Interop/SpeechRecognitionTests.cs"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"d24393ce2418c744bd2c6d8dfa9717843160c20074b04d6f257f5b2512655528"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: RerenderAllAsync_NoSessions_ReturnsCompletedTask: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/LiveSessionStoreTests.cs"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"e587e407e1ba023c351241144e50d1301ec4fa2fe2f5826771c277bf14ef0714"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: StateHasChanged_NoHandle_DoesNotThrow: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/StateHasChangedTests.cs"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"561cb4fc491d8409bc036457c4d2414e8da6008f6a7586fe5856c3dbc8dee66d"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: StateHasChangedAsync_NoHandle_ReturnsCompletedTask: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/StateHasChangedTests.cs"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"d347953c32fecb40d3175b7dc967f0ca2b7d1ba32bca2acfbb217987cd83bd82"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: A_failed_prefetch_does_not_throw: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Query.Tests/PlaceholderDataTests.cs"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"adcc469cc0b359b2e4cd85b8645eeb8ecf4fae736b23038533458e496750b6f4"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: RequestRenderAsync_NoSocket_NoOps: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Live/LiveSessionDirectTests.cs"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"1df513bb14e3c5c8d5b3cc74026b7892cc5f7c491083630d7c055f03de28a09c"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Constructor_AssignsRenderHandleSoStateHasChangedAsyncRoutesToSession: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Live/LiveSessionDirectTests.cs"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd746b5479f8b39df9262c74936477308a3fc711bc3344a79376593166ac2dce"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Leave_IsSafeTwice: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Signaling.Tests/SignalingHubTests.cs"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"e089268ce1942bca5f8a8497d7a26a91b98af44fb75ccb04e3f785cedc97c403"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Optimize_on_a_closed_connection_is_a_no_op: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.SQLite.Tests/SqliteHardeningIntegrationTests.cs"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"47ff23f328ee8f85c1bc2c65dfbe16321d0dcd38a0d9965da3c3d6a92eb9ba13"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: A_sibling_of_wwwroot_that_shares_its_name_prefix_is_fine: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Storage.Tests/BackendAndOptionsTests.cs"},"region":{"startLine":259}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fb5c7c62b60f9593076127633b439fb53e4e1779521dce4f9ce7f22ad58eabb"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Localhost_may_use_http: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Storage.Tests/BackendAndOptionsTests.cs"},"region":{"startLine":301}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed1f21de80ffd2300a5d81639aa4887956c8bbbb774245508f27f7b7116c6c36"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: AFiredSyncWithNoSubscribers_IsHarmless: This method\u0027s body runs code, and no assertion call was recognised in it. Recognised by name: Assert*, *Should*/ShouldBe*, Verify, Expect, Throws, Record, Received/DidNotReceive, MustHaveHappened/MustNotHaveHappened, EnsureSuccessStatusCode and *AndEnsure* \u2014 so verification routed through a helper of your own naming, through a base-class or callback object whose members hold the assertions, or through a harness that fails by throwing under some other name, is not visible to this check and is not counted here. Read it as \u0027no assertion this check knows how to see\u0027, and if that is right, add one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Wasm.Tests/Browser/BackgroundSyncTests.cs"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b5cc98a70da5d33dcde61697624ab3b2c349e28e86dfcd39826189feb4856c8"}},{"ruleId":"D10","level":"warning","message":{"text":"Fixed-sleep synchronisation: OnMountAsync_TrailingAwait_FiresExactlyOneRender: This test starts a background task and then orders itself against it with \u0060Task.Delay(50)\u0060 \u2014 a fixed wait, not a signal that the work is done. Whether it passes depends on how loaded the machine is, which is why a test written this way is green on a developer\u0027s box and random in CI. Wait for the event itself instead: the process\u0027s own exit or output, a completion handle, or a condition polled to a timeout."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Lifecycle/AsyncLifecycleRenderingTests.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"7626cd5acbf34ccebe6a83d10d5a933da5063ecb34282e097249198b95eff3da"}},{"ruleId":"D10","level":"warning","message":{"text":"Fixed-sleep synchronisation: The_session_is_usable_again_after_a_send_times_out: This test starts a background task and then orders itself against it with \u0060Task.Delay(TimeSpan.FromSeconds(5))\u0060 \u2014 a fixed wait, not a signal that the work is done. Whether it passes depends on how loaded the machine is, which is why a test written this way is green on a developer\u0027s box and random in CI. Wait for the event itself instead: the process\u0027s own exit or output, a completion handle, or a condition polled to a timeout."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Live/SendTimeoutTests.cs"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab66a4da610f491df873c967c3f1c82069df2c91bcb1510e7cdb461ecb1ab697"}},{"ruleId":"D10","level":"warning","message":{"text":"Fixed-sleep synchronisation: A_long_lived_context_still_retries_a_later_contention: This test starts a background task and then orders itself against it with \u0060Task.Delay(TimeSpan.FromMilliseconds(2500))\u0060 \u2014 a fixed wait, not a signal that the work is done. Whether it passes depends on how loaded the machine is, which is why a test written this way is green on a developer\u0027s box and random in CI. Wait for the event itself instead: the process\u0027s own exit or output, a completion handle, or a condition polled to a timeout."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.SQLite.EntityFrameworkCore.Tests/RaskSqliteExecutionStrategyTests.cs"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bbc67ffee721881862d17887c942a771ca676eb164029aba4613361e83adc6f"}},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"26f686681466364acbe38b9fb5aa582f138189d1c9f22dcc5409872ec851061e"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Server/RaskEndpointExtensions.cs: src/Rask.Server/RaskEndpointExtensions.cs changed 83 times in last 90 days, max cyclomatic complexity 40 in RaskEndpointExtensions.RunSocketLoop at line 1357. 13 of those changes were fix/bug commits, and the other 70 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Server/RaskEndpointExtensions.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1357}}}],"partialFingerprints":{"codehealthFindingId/v1":"920cea3dd9fa77c01d36cc732fddd96a7a93765c82c2718188cacffa86a86ba9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Component.cs: src/Rask.Core/Component.cs changed 55 times in last 90 days, max cyclomatic complexity 43 in Component.TryInvokeHandlerCoreAsync at line 2270. 12 of those changes were fix/bug commits, and the other 43 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Component.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Component.cs"},"region":{"startLine":2270}}}],"partialFingerprints":{"codehealthFindingId/v1":"43d4ae75c0e117db6b49a6ce39537fc4cee71dbdf282c0fc0280729e70a05590"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/Commands/NewCommand.cs: src/Rask.Cli/Commands/NewCommand.cs changed 50 times in last 90 days, max cyclomatic complexity 30 in NewCommand.ExecuteAsync at line 147. 6 of those changes were fix/bug commits, and the other 44 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/Commands/NewCommand.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/NewCommand.cs"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"c51bd3649287ce608815cfb998cce84faa0206e0619e31be125274349127d421"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Resources/rask-morph.ts: src/Rask.Core/Resources/rask-morph.ts changed 20 times in last 90 days, max cyclomatic complexity 74 in morph at line 503. 3 of those changes were fix/bug commits, and the other 17 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Resources/rask-morph.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"99e872381bfbef3d89fee5eaa4f19404a3d0699ddad23b3ff10a023b5e44d01d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/ComponentFactoryGenerator.cs: src/Rask.Generators/ComponentFactoryGenerator.cs changed 44 times in last 90 days, max cyclomatic complexity 33 in ComponentFactoryGenerator.GetFactoryProperties at line 5119. 5 of those changes were fix/bug commits, and the other 39 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/ComponentFactoryGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":5119}}}],"partialFingerprints":{"codehealthFindingId/v1":"a94f26e3a1f049ef6cab385b51c99be3c68fec27cdf5fbb6b3878b09f74b89d7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/Commands/DeployCommand.cs: src/Rask.Cli/Commands/DeployCommand.cs changed 21 times in last 90 days, max cyclomatic complexity 44 in DeployCommand.ExecuteAsync at line 144. 5 of those changes were fix/bug commits, and the other 16 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/Commands/DeployCommand.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DeployCommand.cs"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"baddd9f9479f267d2d78ec535ce3a3d2086296a01e9d6be7200f062d2f198fc5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Resources/rask-dom.ts: src/Rask.Core/Resources/rask-dom.ts changed 23 times in last 90 days, max cyclomatic complexity 34 in applyDiff at line 158. 1 of those changes was a fix/bug commit, and the other 22 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Resources/rask-dom.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"18d87996725947ceba234771dcd53257a302a934aed616db2e1204ad46b0d342"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Server/Resources/rask.ts: src/Rask.Server/Resources/rask.ts changed 34 times in last 90 days, max cyclomatic complexity 22 in commit at line 1496. 2 of those changes were fix/bug commits, and the other 32 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Server/Resources/rask.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1496}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa41167e68518b0f0d99a1b195103641825bbd38dafda93faa139bf1a763a50a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Batteries.Generators/ModelInputGenerator.cs: src/Rask.Batteries.Generators/ModelInputGenerator.cs changed 12 times in last 90 days, max cyclomatic complexity 62 in ModelInputGenerator.Render at line 686. 1 of those changes was a fix/bug commit, and the other 11 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Batteries.Generators/ModelInputGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelInputGenerator.cs"},"region":{"startLine":686}}}],"partialFingerprints":{"codehealthFindingId/v1":"c57b64a34d894232c9088c88c3c8968d5026be1349c1b538b404511a38bfc61b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Components/Input.cs: src/Rask.Core/Components/Input.cs changed 12 times in last 90 days, max cyclomatic complexity 53 in Input.WriteAttributes at line 237. 1 of those changes was a fix/bug commit, and the other 11 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Components/Input.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Input.cs"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"86e9b463ac46b124bab794b980635d8a64af4e44542fc3cccca431f63d78750a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Wasm/Resources/rask.wasm.ts: src/Rask.Wasm/Resources/rask.wasm.ts changed 32 times in last 90 days, max cyclomatic complexity 19 in trackHeadAsset at line 115. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Wasm/Resources/rask.wasm.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask.wasm.ts"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd9cca76df16b5fb4585c7f4729ca5a389fd8e20e1b6c33084c3aa40ac27996c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Live/LivePayload.cs: src/Rask.Core/Live/LivePayload.cs changed 14 times in last 90 days, max cyclomatic complexity 38 in LivePayload.BuildPayloadUtf8Diff at line 394. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Live/LivePayload.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LivePayload.cs"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"acdb1d008afa74f8ae3324dc83a46d1b78bed8497c0bfc497e7e93b196675a54"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Live/LiveSessionBase.cs: src/Rask.Core/Live/LiveSessionBase.cs changed 21 times in last 90 days, max cyclomatic complexity 22 in LiveSessionBase.WritePayload at line 439. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Live/LiveSessionBase.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/LiveSessionBase.cs"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"b12ca4ba2c0f3fb7fa4ca492490fd8c34c947128ba3147ff9eea498dfa187f6c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Ui/UiSelect.cs: src/Rask.Ui/UiSelect.cs changed 18 times in last 90 days, max cyclomatic complexity 24 in UiSelect.OnKeyAsync at line 528. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Ui/UiSelect.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiSelect.cs"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"0291f38bc9feda5412c9ca521f914c45f406703db02783d21259aff29fcc6937"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs: src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs changed 18 times in last 90 days, max cyclomatic complexity 23 in UiKitDataInputDemo.Render at line 47. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitDataInputDemo.cs"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"23fc6d19227eca5372e21da1fd48e115d8d03ff0e91774c5971733e9d745c11d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/External/ExternalGenerator.cs: src/Rask.Generators/External/ExternalGenerator.cs changed 10 times in last 90 days, max cyclomatic complexity 41 in ExternalGenerator.Emit at line 792. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/External/ExternalGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/External/ExternalGenerator.cs"},"region":{"startLine":792}}}],"partialFingerprints":{"codehealthFindingId/v1":"a972fb287fe75840277523a98c41db21109ff0a71631410fd71e1b13da730e5a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Wasm/Resources/rask-wasm-api.ts: src/Rask.Wasm/Resources/rask-wasm-api.ts changed 21 times in last 90 days, max cyclomatic complexity 18 in applyManifest at line 15. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Wasm/Resources/rask-wasm-api.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"f07130f9b2e76c76d1a6203fb2a6828dd9a4384a73c2ad44ccb016d9bec0642e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask/RaskBatteryWiring.cs: src/Rask/RaskBatteryWiring.cs changed 16 times in last 90 days, max cyclomatic complexity 22 in RaskBatteryWiring.Apply at line 90. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask/RaskBatteryWiring.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskBatteryWiring.cs"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae54b5f1a61335a3af49260f72186bcc10915ba24c5df0b50c37114a7cea48fe"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/Commands/DbCommand.cs: src/Rask.Cli/Commands/DbCommand.cs changed 11 times in last 90 days, max cyclomatic complexity 32 in DbCommand.ExecuteAsync at line 87. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/Commands/DbCommand.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DbCommand.cs"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"23017fec4da326cb5bbece840911a996a8ab92b856e81d8c8374554b5551357e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Element.cs: src/Rask.Core/Element.cs changed 13 times in last 90 days, max cyclomatic complexity 25 in Element.WriteAttributes at line 359. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Element.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Element.cs"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"67d4feaf597597468343d098c42f2615b81bb2b30496ee6ddf4c002391104d51"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Ui/UiIcon.cs: src/Rask.Ui/UiIcon.cs changed 4 times in last 90 days, max cyclomatic complexity 80 in UiIcon.Shapes at line 94. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Ui/UiIcon.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiIcon.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"db122d9062e3686c96fae12563c5daeadb10e80e9fdabe792fc0890e0bcba855"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/Commands/DevCommand.cs: src/Rask.Cli/Commands/DevCommand.cs changed 20 times in last 90 days, max cyclomatic complexity 16 in DevCommand.ExecuteAsync at line 86. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/Commands/DevCommand.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DevCommand.cs"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2ad63671abcf40f00c27f4de268d29ebbd00c96c1cc203d0c32b2f04a0e33c1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/RoutesGenerator.cs: src/Rask.Generators/RoutesGenerator.cs changed 12 times in last 90 days, max cyclomatic complexity 26 in RoutesGenerator.Emit at line 649. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/RoutesGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/RoutesGenerator.cs"},"region":{"startLine":649}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfd1bc495d67b0e7afe137fc4fb82079d7f123e1fe82024f33367b95226a920e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Live/FrameDiffer.cs: src/Rask.Core/Live/FrameDiffer.cs changed 12 times in last 90 days, max cyclomatic complexity 26 in FrameDiffer.DiffKeyedSiblings at line 814. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Live/FrameDiffer.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/FrameDiffer.cs"},"region":{"startLine":814}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5c7fcbcb04aa1e8275d795317aac1b70dcfbd5462449a8ce57c16b27b03fc0c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Wasm/WasmPrerender.cs: src/Rask.Wasm/WasmPrerender.cs changed 12 times in last 90 days, max cyclomatic complexity 22 in WasmPrerender.PatchManifest at line 414. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Wasm/WasmPrerender.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/WasmPrerender.cs"},"region":{"startLine":414}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b9d5cac681a4c3fbf5442944d8816819d97759ecb0800f665e437cb7639803c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask/RaskApp.cs: src/Rask/RaskApp.cs changed 13 times in last 90 days, max cyclomatic complexity 18 in RaskApp.Build at line 137. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask/RaskApp.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskApp.cs"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"48a283887606a6b2cc150b9f87c31970cc695a7cbdc7fd1ee699c123d85c3448"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Forms/BindingHelpers.cs: src/Rask.Core/Forms/BindingHelpers.cs changed 11 times in last 90 days, max cyclomatic complexity 21 in BindingHelpers.DefaultInputType at line 66. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Forms/BindingHelpers.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/BindingHelpers.cs"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa0ec2fa6008a3fbe487fdb5fa9db6665d96e3655843935fabc840a3a0588506"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Ui/UiClassNames.cs: src/Rask.Ui/UiClassNames.cs changed 13 times in last 90 days, max cyclomatic complexity 17 in UiClassNames.MaskShape at line 648. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Ui/UiClassNames.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiClassNames.cs"},"region":{"startLine":648}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3429014a3ec6fa323e5abba4d41faf0fd0df58fad2a9883f37765290dda6fc3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Components/Select.cs: src/Rask.Core/Components/Select.cs changed 13 times in last 90 days, max cyclomatic complexity 17 in Select.WriteAttributes at line 223. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Components/Select.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Select.cs"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dae4048fa9432fc07d8544ff57fc100951d5182924a598ae46a4ca868faf48f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Components/Textarea.cs: src/Rask.Core/Components/Textarea.cs changed 10 times in last 90 days, max cyclomatic complexity 21 in Textarea.WriteAttributes at line 113. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Components/Textarea.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Textarea.cs"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d797e9d52a48bd325de310defa5c913ae13539d6fa53c410f0f4e3983f27e7a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Batteries.Generators/CqrsDispatchGenerator.cs: src/Rask.Batteries.Generators/CqrsDispatchGenerator.cs changed 11 times in last 90 days, max cyclomatic complexity 19 in CqrsDispatchGenerator.GetCandidate at line 65. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Batteries.Generators/CqrsDispatchGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsDispatchGenerator.cs"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ec7f9895a105cb211dd3357d9c4e9b1f40e1138438b7c5dec31e48cc169391e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators.Shared/GeneratedModelShape.cs: src/Rask.Generators.Shared/GeneratedModelShape.cs changed 8 times in last 90 days, max cyclomatic complexity 25 in ValueObjectCollector.Of at line 798. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators.Shared/GeneratedModelShape.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/GeneratedModelShape.cs"},"region":{"startLine":798}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf5bc601733e60e63366ff63d85399b98908714367be9f069afab86b21831acc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Forms/EditContext.cs: src/Rask.Core/Forms/EditContext.cs changed 7 times in last 90 days, max cyclomatic complexity 27 in EditContext.ValidateFieldAsync at line 716. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Forms/EditContext.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/EditContext.cs"},"region":{"startLine":716}}}],"partialFingerprints":{"codehealthFindingId/v1":"5de1c406d72e20eb59591117de91e0a9a4bc1db907477033893a4580a35a2c64"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs: src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs changed 7 times in last 90 days, max cyclomatic complexity 26 in BakeScopedAssetsTask.BakeFromAssemblies at line 176. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3d4a598ff9c023fe0025524a85eae3a42aa67e020e5c39eea86e58bfb983793"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.External/extractor/extract-props.ts: src/Rask.External/extractor/extract-props.ts changed 4 times in last 90 days, max cyclomatic complexity 38 in serialize at line 499. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.External/extractor/extract-props.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":499}}}],"partialFingerprints":{"codehealthFindingId/v1":"e94756c77817989194d68b4a49c8dc7ad8fbdc2416ada1db95b717c9bdc1207a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Batteries.Generators/ModelRegistryGenerator.cs: src/Rask.Batteries.Generators/ModelRegistryGenerator.cs changed 10 times in last 90 days, max cyclomatic complexity 15 in ModelRegistryGenerator.EmitConventions at line 527. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Batteries.Generators/ModelRegistryGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/ModelRegistryGenerator.cs"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"43b721e7c11d32befd986d0d5ef81b0f989f818a64a8201aa03dbf3ad7921d41"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Resources/rask-events.ts: src/Rask.Core/Resources/rask-events.ts changed 10 times in last 90 days, max cyclomatic complexity 15 in (anonymous) at line 319. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Resources/rask-events.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-events.ts"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"e957ba1fa14b92919ca9030930c2ec31564e2892f0e18e637a43f54cb7456da0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.DevTools/Probe/DevToolsComponentNode.cs: src/Rask.DevTools/Probe/DevToolsComponentNode.cs changed 8 times in last 90 days, max cyclomatic complexity 18 in DevToolsTreeSnapshotter.BadgeOf at line 202. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.DevTools/Probe/DevToolsComponentNode.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Probe/DevToolsComponentNode.cs"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"c45a9c6851cf9832ff4b94bb551b04cfdd2b24955e3bbc5403f09c6fa2c8fbde"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.External.Tasks/WriteExternalBuildInputsTask.cs: src/Rask.External.Tasks/WriteExternalBuildInputsTask.cs changed 6 times in last 90 days, max cyclomatic complexity 23 in WriteExternalBuildInputsTask.Execute at line 71. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.External.Tasks/WriteExternalBuildInputsTask.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/WriteExternalBuildInputsTask.cs"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c06d593cade7613023d3c6d99b693af49decca81e7be0b870ea98b4f0a4e1c0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Ui/UiFileInput.cs: src/Rask.Ui/UiFileInput.cs changed 9 times in last 90 days, max cyclomatic complexity 15 in UiFileInput.Render at line 114. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Ui/UiFileInput.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiFileInput.cs"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9ff9ffcf698652e0a162670db26c9ab9309b36ef4deea4d8c40a0a1741398a9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Wasm/PrerenderShell.cs: src/Rask.Wasm/PrerenderShell.cs changed 7 times in last 90 days, max cyclomatic complexity 19 in PrerenderShell.StripComments at line 390. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Wasm/PrerenderShell.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/PrerenderShell.cs"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"edadffec6fa021509a5e177fd567a67d7c0c9389abaee7a96c729f65837ed56c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Forms/ExpressionAccessor.cs: src/Rask.Core/Forms/ExpressionAccessor.cs changed 7 times in last 90 days, max cyclomatic complexity 18 in ExpressionAccessor.TryEvaluate at line 161. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Forms/ExpressionAccessor.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/ExpressionAccessor.cs"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1bf1a3e1386e3723bd1a7a2e250774141e36435179e2787f19520784e54e65a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Batteries.Generators/CqrsCodecGenerator.cs: src/Rask.Batteries.Generators/CqrsCodecGenerator.cs changed 7 times in last 90 days, max cyclomatic complexity 18 in CqrsCodecGenerator.Build at line 488. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Batteries.Generators/CqrsCodecGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/CqrsCodecGenerator.cs"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ba42c10cd45430fc48389f2e78a0e01eb1d4aaac99ad02424a154397986411a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/ArgumentSchema.cs: src/Rask.Cli/ArgumentSchema.cs changed 6 times in last 90 days, max cyclomatic complexity 21 in ArgumentSchema.Parse at line 164. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/ArgumentSchema.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/ArgumentSchema.cs"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"abc72027c323523d60c034dd0d7c6cffd36946111097c60e5aeb2d97a4fcbea2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/Analyzers/BuilderEntry.cs: src/Rask.Generators/Analyzers/BuilderEntry.cs changed 6 times in last 90 days, max cyclomatic complexity 21 in BuilderEntry.TryReadChain at line 173. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/Analyzers/BuilderEntry.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/BuilderEntry.cs"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"89760dd719615a05e382707e41d56e13c415ff68e7768cf3da56268d8474212b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Components/Svg/SvgElement.cs: src/Rask.Core/Components/Svg/SvgElement.cs changed 7 times in last 90 days, max cyclomatic complexity 18 in SvgElement.WriteAttributes at line 110. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Components/Svg/SvgElement.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Svg/SvgElement.cs"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"13dcf1c69fec210537803fdb124fc5ccff77304d9ed820497b15c0683bf2ecbc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.External/client/lit.ts: src/Rask.External/client/lit.ts changed 5 times in last 90 days, max cyclomatic complexity 25 in renderChildren at line 128. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.External/client/lit.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/lit.ts"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1b87c416c96488f57bdf6cdad46f91401c2f014056bdb0e856c604d4c67fc6f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators.Shared/WireShape.cs: src/Rask.Generators.Shared/WireShape.cs changed 6 times in last 90 days, max cyclomatic complexity 20 in WireShape.Classify at line 172. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators.Shared/WireShape.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/WireShape.cs"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"08b18944c6a6c88a0c24fd06cf3843caefa8a9ee89459bad1db3179edf5e14b4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Spa.Hosting/RaskSpaEndpointExtensions.cs: src/Rask.Spa.Hosting/RaskSpaEndpointExtensions.cs changed 6 times in last 90 days, max cyclomatic complexity 20 in RaskSpaEndpointExtensions.UseRaskSpa at line 100. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Spa.Hosting/RaskSpaEndpointExtensions.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/RaskSpaEndpointExtensions.cs"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa3f7a4df2eed1ed9e321f4064dc8e4741087ffac522b0251dd45813465dfea5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Data/BulkInsertPlan.cs: src/Rask.Data/BulkInsertPlan.cs changed 6 times in last 90 days, max cyclomatic complexity 19 in BulkInsertPlan.Build at line 94. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Data/BulkInsertPlan.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/BulkInsertPlan.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c9360a784b29f8d6d01ae97dbaf110b883ed06b96efc839522dba82e488975a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Components/Button.cs: src/Rask.Core/Components/Button.cs changed 7 times in last 90 days, max cyclomatic complexity 16 in Button.WriteAttributes at line 94. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Components/Button.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Button.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e9208c85ecd94e3725803ad41104e6f772b8146bea1f0a3ef49e39f9ffea23d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.External/client/angular.ts: src/Rask.External/client/angular.ts changed 4 times in last 90 days, max cyclomatic complexity 26 in renderChildren at line 223. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.External/client/angular.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/angular.ts"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"445ce9d9231ed4aeae006bfc3b91cdd9d0ec6adee8d45e7b9c90964834c5ca3f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Live/HandlerFrameShape.cs: src/Rask.Core/Live/HandlerFrameShape.cs changed 6 times in last 90 days, max cyclomatic complexity 17 in HandlerFrameShape.ShapeOf at line 170. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Live/HandlerFrameShape.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/HandlerFrameShape.cs"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"d407d17b46cc56b38c930ca1881a5dde3caeaa73440e517b64d9aef9046cdb87"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Resources/rask-deverror.ts: src/Rask.Core/Resources/rask-deverror.ts changed 5 times in last 90 days, max cyclomatic complexity 20 in showDevError at line 232. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Resources/rask-deverror.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-deverror.ts"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"79e106143b52b2e6a36d1fbe2d4f7f8899103d3535638b108398c74d127fb3e2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.DevTools/Resources/panel/panel-client.ts: src/Rask.DevTools/Resources/panel/panel-client.ts changed 6 times in last 90 days, max cyclomatic complexity 16 in (anonymous) at line 201. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.DevTools/Resources/panel/panel-client.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/panel/panel-client.ts"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"e72d08c3a77edb4ce97878d2cbf011d89d2d2ba55a8cf0a51982dfe3786c22a5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/Analyzers/RootShellAnalyzer.cs: src/Rask.Generators/Analyzers/RootShellAnalyzer.cs changed 6 times in last 90 days, max cyclomatic complexity 15 in RootShellAnalyzer.Analyze at line 80. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/Analyzers/RootShellAnalyzer.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/RootShellAnalyzer.cs"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"647dd944d12938ba092c978d38cd826b9278fb3c1f50242c91a22c39e921732b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/Translations/TranslationCatalogGenerator.cs: src/Rask.Generators/Translations/TranslationCatalogGenerator.cs changed 4 times in last 90 days, max cyclomatic complexity 22 in TranslationCatalogGenerator.EmitFamily at line 133. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/Translations/TranslationCatalogGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Translations/TranslationCatalogGenerator.cs"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"a824e1d98972ba977ddc1c06b1e23d63ea6f09877917fa777b474aac5f2997b3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Storage/Upload/ContentSniffer.cs: src/Rask.Storage/Upload/ContentSniffer.cs changed 2 times in last 90 days, max cyclomatic complexity 41 in ContentSniffer.Signature at line 61. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Storage/Upload/ContentSniffer.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Upload/ContentSniffer.cs"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bd761eb15a0415aee7d1d64bf37af020663704adb46c15e32fbcf5d9fa99d37"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Data/ReadModelRegistry.cs: src/Rask.Data/ReadModelRegistry.cs changed 4 times in last 90 days, max cyclomatic complexity 19 in ReadModelRegistry.MapColumns at line 202. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Data/ReadModelRegistry.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/ReadModelRegistry.cs"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"d49920551a3c2a124070699c3f81d9183786ea32f22f63d3b6a44ca4576eaa26"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/ScopedAssets/ScopedAssetRegistry.cs: src/Rask.Core/ScopedAssets/ScopedAssetRegistry.cs changed 5 times in last 90 days, max cyclomatic complexity 15 in ScopedAssetRegistry.EnsureBundle at line 576. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/ScopedAssets/ScopedAssetRegistry.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/ScopedAssets/ScopedAssetRegistry.cs"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"67d70fb36c2a87b4b8b8d0ed1f697b74a67904a3444ea762a29d56ac5803d1a7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.DevTools/Resources/host/bridge.ts: src/Rask.DevTools/Resources/host/bridge.ts changed 5 times in last 90 days, max cyclomatic complexity 15 in handle at line 52. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.DevTools/Resources/host/bridge.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/bridge.ts"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"b26f9b530d0c4d51c9e0ddc61a3a7794981ddf6bdeae35da2faa7d0c353c65eb"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/ComponentScopedJsGenerator.cs: src/Rask.Generators/ComponentScopedJsGenerator.cs changed 5 times in last 90 days, max cyclomatic complexity 15 in ComponentScopedJsGenerator.Emit at line 229. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/ComponentScopedJsGenerator.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentScopedJsGenerator.cs"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"428953f5272e2d4cee3059a7cf2d44d4595dbeecba98481f01696f50e251c7f6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/Scaffolding/TemplateMarkers.cs: src/Rask.Cli/Scaffolding/TemplateMarkers.cs changed 4 times in last 90 days, max cyclomatic complexity 17 in TemplateMarkers.Apply at line 56. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/Scaffolding/TemplateMarkers.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Scaffolding/TemplateMarkers.cs"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"e29bccbad4b48070360648c6038d030ca6e5d4d95d8f636c3653cfb0d64ae539"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs: src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs changed 4 times in last 90 days, max cyclomatic complexity 17 in MissingKeyAnalyzer.Analyze at line 77. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Analyzers/MissingKeyAnalyzer.cs"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"56633a70093042814a87e9da811573ed01de5f07e40c3f2ecff01284f2db40b0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Core/Components/Link.cs: src/Rask.Core/Components/Link.cs changed 4 times in last 90 days, max cyclomatic complexity 16 in Link.WriteAttributes at line 91. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Components/Link.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Components/Link.cs"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"a653434edaec4ea3a37f5dc74c6bd55fbae08d066582005e74c3cefc54000ed0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.SQLite.EntityFrameworkCore/RangeExclusionDdl.cs: src/Rask.SQLite.EntityFrameworkCore/RangeExclusionDdl.cs changed 3 times in last 90 days, max cyclomatic complexity 20 in RangeExclusionDdl.TableOf at line 197. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.SQLite.EntityFrameworkCore/RangeExclusionDdl.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite.EntityFrameworkCore/RangeExclusionDdl.cs"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"8364b0efac074500828441cd0bf4827c22eee90dbb68651cf57f7f6536f9c423"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators/Blazor/BlazorParameters.cs: src/Rask.Generators/Blazor/BlazorParameters.cs changed 3 times in last 90 days, max cyclomatic complexity 20 in BlazorParameters.Read at line 122. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators/Blazor/BlazorParameters.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Blazor/BlazorParameters.cs"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"74b0a2abeacd3d5e946c9cf2d78a2714df72f5d09fed6f2a38bb5d40c914f86e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cqrs.Server/RaskCqrsEndpointExtensions.cs: src/Rask.Cqrs.Server/RaskCqrsEndpointExtensions.cs changed 3 times in last 90 days, max cyclomatic complexity 18 in RaskCqrsEndpointExtensions.HandleAsync at line 217. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cqrs.Server/RaskCqrsEndpointExtensions.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cqrs.Server/RaskCqrsEndpointExtensions.cs"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"393bc282773489960dea6bdc952cd39bb5f88e08235293f1bcab1084e3543c09"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/HostProbe.cs: src/Rask.Cli/HostProbe.cs changed 2 times in last 90 days, max cyclomatic complexity 26 in HostFacts.Parse at line 54. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/HostProbe.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/HostProbe.cs"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa56e54689f064a566daed611a792d5cb222bfda0804f56c0b721e66f5ec7c8d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Server/Resources/rask-http-transport.ts: src/Rask.Server/Resources/rask-http-transport.ts changed 3 times in last 90 days, max cyclomatic complexity 15 in (anonymous) at line 356. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Server/Resources/rask-http-transport.ts\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask-http-transport.ts"},"region":{"startLine":356}}}],"partialFingerprints":{"codehealthFindingId/v1":"d79659b6b5c4df77068795736ddb64e635054fa01fbc75f6de2a7705b944f451"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Generators.Shared/SymbolRegistration.cs: src/Rask.Generators.Shared/SymbolRegistration.cs changed 3 times in last 90 days, max cyclomatic complexity 15 in SymbolRegistration.DescribeUnnameableWithRemedy at line 84. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Generators.Shared/SymbolRegistration.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.Shared/SymbolRegistration.cs"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba1fda4d31ae8fdec6a60fc44fcf3d0a165041d5675d91714e62ddf01723b200"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.SQLite/SqlitePragmas.cs: src/Rask.SQLite/SqlitePragmas.cs changed 3 times in last 90 days, max cyclomatic complexity 15 in SqlitePragmas.BuildScript at line 20. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.SQLite/SqlitePragmas.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite/SqlitePragmas.cs"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c6ab9f2477d29d92abdc3fc5f38a609d3e3624b154c55fb41190abe05935692"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/HostSetup.cs: src/Rask.Cli/HostSetup.cs changed 2 times in last 90 days, max cyclomatic complexity 22 in HostSetup.EnsureReadyAsync at line 54. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/HostSetup.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/HostSetup.cs"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6145d7eb8d7bd72e5885357e3be7068a799f21db205b5eaca217b0ffe6ed998"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Storage/Backends/AzureAccount.cs: src/Rask.Storage/Backends/AzureAccount.cs changed 2 times in last 90 days, max cyclomatic complexity 21 in AzureAccount.Parse at line 41. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Storage/Backends/AzureAccount.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Backends/AzureAccount.cs"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"194a4c9bcf14ad621e388f235609f82973115bad23b925e73153221da30937c0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Ui/UiTree.cs: src/Rask.Ui/UiTree.cs changed 2 times in last 90 days, max cyclomatic complexity 21 in UiTree.OnKeyAsync at line 365. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Ui/UiTree.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Ui/UiTree.cs"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bab0c67ec1b9a96db48358897b22f34375925d377430b0bc31478ec768badf7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.DevTools/Panel/DevToolsPageErrorReceiver.cs: src/Rask.DevTools/Panel/DevToolsPageErrorReceiver.cs changed 2 times in last 90 days, max cyclomatic complexity 18 in DevToolsPageErrorReceiver.Record at line 62. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.DevTools/Panel/DevToolsPageErrorReceiver.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Panel/DevToolsPageErrorReceiver.cs"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a3489571516e2f41791a18ab2421cd71e764e1b48b2638e00e481d515be4841"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Storage/Upload/SafeFileName.cs: src/Rask.Storage/Upload/SafeFileName.cs changed 2 times in last 90 days, max cyclomatic complexity 18 in SafeFileName.Clean at line 33. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Storage/Upload/SafeFileName.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Upload/SafeFileName.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"66c3559db555b7cf1393c320081c1c1894a4bb5253390195b8ee6bb6559da962"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.SQLite.EntityFrameworkCore/FullTextSearchDdl.cs: src/Rask.SQLite.EntityFrameworkCore/FullTextSearchDdl.cs changed 2 times in last 90 days, max cyclomatic complexity 16 in FullTextSearchDdl.TableOf at line 334. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.SQLite.EntityFrameworkCore/FullTextSearchDdl.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite.EntityFrameworkCore/FullTextSearchDdl.cs"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"16bf997c19c0ae09e43a45ea18241a75c169930a8940055c70991259c470f51c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: src/Rask.Cli/HostBootstrap.cs: src/Rask.Cli/HostBootstrap.cs changed 2 times in last 90 days, max cyclomatic complexity 15 in HostBootstrap.Plan at line 107. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cli/HostBootstrap.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/HostBootstrap.cs"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cc9fba6290e3f132fc0cb6a715010a929618970373476579d6886ccb813e549"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: src/Rask.Core/Live/QuiescenceScope.cs: src/Rask.Core/Live/QuiescenceScope.cs changed 5 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 4 (its worst body is QuiescenceScope.TrySnapshotPending at line 173), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(core): find a render\u0027s quiescence scope through the async flow only\u201D; \u201Cfix(ssr): track the paint, not the hook, for quiescence\u201D; \u201Cfix(ssr): hand the quiescence pass to the lifecycle sync context\u201D; \u201Cfix(core): let the running flow\u0027s quiescence scope beat a live one left on the thread\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Core/Live/QuiescenceScope.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/QuiescenceScope.cs"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfec3c077d40cbdb0e75f84d4d9e2ba9c08e81b2db404d41830658491f66e969"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: src/Rask.Cqrs.Client/RaskCqrsClientServiceCollectionExtensions.cs: src/Rask.Cqrs.Client/RaskCqrsClientServiceCollectionExtensions.cs changed 5 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 5 (its worst body is RaskCqrsClientServiceCollectionExtensions.InstallRemoteInvokers at line 86), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(cqrs): install client invokers under the gate, so a concurrent registration waits\u201D; \u201Cfix(cqrs): honour the client timeout, and resume a dropped upload chunk (#907)\u201D; \u201Cfix: clear the native leftovers the prose kept, including the ones that shipped (#825)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Cqrs.Client/RaskCqrsClientServiceCollectionExtensions.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cqrs.Client/RaskCqrsClientServiceCollectionExtensions.cs"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b1d3218e28ad35f5e449ae0f33c083ec1e3ca11ed226225b748f3816117a3e9"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: src/Rask.Storage/RaskStorageServiceCollectionExtensions.cs: src/Rask.Storage/RaskStorageServiceCollectionExtensions.cs changed 5 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 5 (its worst body is RaskStorageServiceCollectionExtensions.CreateBackend at line 123), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(batteries): stop the pollers filling the console with their own SQL\u201D; \u201Cfix(storage): run without Rask.Core on every lane; bind Rask:Storage\u201D; \u201Cfix(storage): the sweep keeps off buckets it cannot prove are its own\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.Storage/RaskStorageServiceCollectionExtensions.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/RaskStorageServiceCollectionExtensions.cs"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"142fccf9a2a0511725d36687d905af261143d9e14dc9793fddd8fe66b6e630d8"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: src/Rask.SQLite/SqliteBusyRetry.cs: src/Rask.SQLite/SqliteBusyRetry.cs changed 5 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 11 (its worst body is SqliteBusyRetry.ExecAsync at line 28), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(sqlite): re-run the transaction when SQLite rolls a contended COMMIT back (#582)\u201D; \u201Cfix(sqlite): stop the busy retry re-issuing BEGIN inside its own transaction (#540)\u201D; \u201Cfix(sqlite): harden and diagnose the raw immediate-transaction path against pooled-handle reuse (#431)\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-06-23..2026-09-21, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-23 10:50:14 \u002B02:00\u0027 --until=\u00272026-09-21 10:50:14 \u002B02:00\u0027 --full-history --no-merges -- src/Rask.SQLite/SqliteBusyRetry.cs\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite/SqliteBusyRetry.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"66a831e4438d79e67c7ef87a0b12dc511d852e548dc5ffa7f6bca8ac4e2df6ef"}},{"ruleId":"D17","level":"warning","message":{"text":"BarePragmaDisable: #pragma warning disable CA2255 \u2014 the disable is closed again below, so its scope is not the problem; what it records is no reason: there is nothing on the directive line, and no ordinary comment attached to it either side. A suppression is a decision somebody made, and without the reason the next reader cannot tell a considered exception from an unexamined one, so it is never revisited and it outlives the code it was written for. Put the reason on the directive line \u2014 what makes this site legitimately different \u2014 or fix what the rule is pointing at and delete the pair. A rationale in the member\u0027s documentation comment does not clear this row and is not meant to: it explains the member to its callers, and the next person to touch the suppression is not reading it for that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Routing/__RaskDefaultFallback.cs"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"6da9c6e4d76c8192fd29324237a9394ddcb4457a4f3115ae41c12edf4099726e"}},{"ruleId":"D17","level":"error","message":{"text":"EmptyCatchBlock: empty catch block \u2014 the error is discarded with nothing recorded, so a failure here leaves no trace anywhere. Narrow the catch to the exception you actually expect, record it through whatever this codebase already uses to report problems, or \u2014 where swallowing really is correct, as it often is on a teardown/dispose path where throwing would mask the original failure \u2014 write down WHY in a comment on the catch. The comment has to give the reason: a note that only restates the swallow (\u0022ignored\u0022, \u0022do nothing\u0022) is read as no explanation at all and leaves this row in place. Any of the three makes the decision reviewable; all three clear this row."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskDrainService.cs"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"eea57d8d749701db59340413f420e74b5258a2e666270cd571c383ce071cec3f"}},{"ruleId":"D17","level":"error","message":{"text":"EmptyCatchBlock: empty catch block \u2014 the error is discarded with nothing recorded, so a failure here leaves no trace anywhere. Narrow the catch to the exception you actually expect, record it through whatever this codebase already uses to report problems, or \u2014 where swallowing really is correct, as it often is on a teardown/dispose path where throwing would mask the original failure \u2014 write down WHY in a comment on the catch. The comment has to give the reason: a note that only restates the swallow (\u0022ignored\u0022, \u0022do nothing\u0022) is read as no explanation at all and leaves this row in place. Any of the three makes the decision reviewable; all three clear this row."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1364}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5b5ceafceaed5bcf53bb98b0a5e96c1de05810c2096d35bdcb6acbdc3e21b4c"}},{"ruleId":"D17","level":"error","message":{"text":"EmptyCatchBlock: empty catch block \u2014 the error is discarded with nothing recorded, so a failure here leaves no trace anywhere. Narrow the catch to the exception you actually expect, record it through whatever this codebase already uses to report problems, or \u2014 where swallowing really is correct, as it often is on a teardown/dispose path where throwing would mask the original failure \u2014 write down WHY in a comment on the catch. The comment has to give the reason: a note that only restates the swallow (\u0022ignored\u0022, \u0022do nothing\u0022) is read as no explanation at all and leaves this row in place. Any of the three makes the decision reviewable; all three clear this row."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1443}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dee8d4bd54689267681195512c6e42306c9ee4bca8262bd4ab271164509bcd7"}},{"ruleId":"D17","level":"error","message":{"text":"EmptyCatchBlock: empty catch block \u2014 the error is discarded with nothing recorded, so a failure here leaves no trace anywhere. Narrow the catch to the exception you actually expect, record it through whatever this codebase already uses to report problems, or \u2014 where swallowing really is correct, as it often is on a teardown/dispose path where throwing would mask the original failure \u2014 write down WHY in a comment on the catch. The comment has to give the reason: a note that only restates the swallow (\u0022ignored\u0022, \u0022do nothing\u0022) is read as no explanation at all and leaves this row in place. Any of the three makes the decision reviewable; all three clear this row."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1600}}}],"partialFingerprints":{"codehealthFindingId/v1":"4266554e63931aba911846d22b55cb37fbe960681be02f1177dec13c8622eb2f"}},{"ruleId":"D17","level":"error","message":{"text":"EmptyCatchBlock: empty catch block \u2014 the error is discarded with nothing recorded, so a failure here leaves no trace anywhere. Narrow the catch to the exception you actually expect, record it through whatever this codebase already uses to report problems, or \u2014 where swallowing really is correct, as it often is on a teardown/dispose path where throwing would mask the original failure \u2014 write down WHY in a comment on the catch. The comment has to give the reason: a note that only restates the swallow (\u0022ignored\u0022, \u0022do nothing\u0022) is read as no explanation at all and leaves this row in place. Any of the three makes the decision reviewable; all three clear this row."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2218}}}],"partialFingerprints":{"codehealthFindingId/v1":"d26e1f04faf694f81b536b813cfb0d32aa4ca241cf8ad14da1d06ee09e1292c7"}},{"ruleId":"D17","level":"error","message":{"text":"EmptyCatchBlock: empty catch block \u2014 the error is discarded with nothing recorded, so a failure here leaves no trace anywhere. Narrow the catch to the exception you actually expect, record it through whatever this codebase already uses to report problems, or \u2014 where swallowing really is correct, as it often is on a teardown/dispose path where throwing would mask the original failure \u2014 write down WHY in a comment on the catch. The comment has to give the reason: a note that only restates the swallow (\u0022ignored\u0022, \u0022do nothing\u0022) is read as no explanation at all and leaves this row in place. Any of the three makes the decision reviewable; all three clear this row."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"6656d5a0f1fbeba46b465eb9a61bfd12eb37964962b91ab6df6d7b9789a5ae21"}},{"ruleId":"D17","level":"warning","message":{"text":"BarePragmaDisable repeated across 13 files: The identical BarePragmaDisable (\u0060#pragma warning disable RASK014\u0060) appears in 13 files (31 occurrences) \u2014 a single repo-wide policy (e.g. a Directory.Build.props decision or an idiomatic suppression), not 31 independent debts. Decide it once centrally rather than file-by-file. (Every occurrence still counts toward the score and metrics.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Benchmarks.VsBlazor/Benchmarks/Dispatch_PinnedBenchmarks.cs"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f68e06d2a4e9db2f75c10c92c70a14e14806d761e0cfa00da8e6063f35740e8"}},{"ruleId":"D17","level":"warning","message":{"text":"BarePragmaDisable: #pragma warning disable ASP0006 \u2014 the disable is closed again below, so its scope is not the problem; what it records is no reason: there is nothing on the directive line, and no ordinary comment attached to it either side. A suppression is a decision somebody made, and without the reason the next reader cannot tell a considered exception from an unexamined one, so it is never revisited and it outlives the code it was written for. Put the reason on the directive line \u2014 what makes this site legitimately different \u2014 or fix what the rule is pointing at and delete the pair. A rationale in the member\u0027s documentation comment does not clear this row and is not meant to: it explains the member to its callers, and the next person to touch the suppression is not reading it for that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Benchmarks.VsBlazor/Components/AttributeHeavyElements.cs"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"68b29db5030fe5912cae00d284f7d2252d07e1e40b32be807de6d0fa48196bc9"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // the tests need the very instance they hand to the render context \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/BuilderCallbackResetTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"2302ca78aa372b08eb3d7ca6fbebcb4bc0b1bf32b657513108cce5bbc43be0fd"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // the tests need the very instance they hand to the render context \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/BuilderHoistTests.cs"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bde4e8cad42395b25e4f8aef6625e3df7dcf95d6cd5aaf35cd62676d564a952"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // the tests need the very instance they hand to the render context \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/BuilderLifecycleTests.cs"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e7c2dd0bd032b3235035b59ae66b5e8471c4b677355bf1584e7aa21d28a4256"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // the tests need the very instance they hand to the render context \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/BuilderRenderPathTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6e5adcd2ad16049e19165560bbf680aee8a80d4331799d25877ed7ac92e3b97"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // the tests need the very instance they hand to the render context \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/BuilderResetTests.cs"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"e80b42b1ee8aaf72e6abe961c2e6f6b148811e0cd961fa7c519320b57390b31d"}},{"ruleId":"D17","level":"warning","message":{"text":"BarePragmaDisable: #pragma warning disable RASK044 \u2014 the disable is closed again below, so its scope is not the problem; what it records is no reason: there is nothing on the directive line, and no ordinary comment attached to it either side. A suppression is a decision somebody made, and without the reason the next reader cannot tell a considered exception from an unexamined one, so it is never revisited and it outlives the code it was written for. Put the reason on the directive line \u2014 what makes this site legitimately different \u2014 or fix what the rule is pointing at and delete the pair. A rationale in the member\u0027s documentation comment does not clear this row and is not meant to: it explains the member to its callers, and the next person to touch the suppression is not reading it for that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/BuilderCallbackTests.cs"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c3cdd8d40441a502be9991fa643e1c26cffc77c01a57d1ab0e371d66dba185c"}},{"ruleId":"D17","level":"warning","message":{"text":"BarePragmaDisable: #pragma warning disable RASK044 \u2014 the disable is closed again below, so its scope is not the problem; what it records is no reason: there is nothing on the directive line, and no ordinary comment attached to it either side. A suppression is a decision somebody made, and without the reason the next reader cannot tell a considered exception from an unexamined one, so it is never revisited and it outlives the code it was written for. Put the reason on the directive line \u2014 what makes this site legitimately different \u2014 or fix what the rule is pointing at and delete the pair. A rationale in the member\u0027s documentation comment does not clear this row and is not meant to: it explains the member to its callers, and the next person to touch the suppression is not reading it for that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/BuilderCallbackTests.cs"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"705619288ee88a8cc7014e68a01ffe8fa2960fdc09a910ae687b60db6887f5b3"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable repeated across 84 files: The identical FileScopedPragmaDisable (\u0060#pragma warning disable RASK014 // test-defined Component subclasses have no generated factories\u0060) appears in 84 files (84 occurrences) \u2014 a single repo-wide policy (e.g. a Directory.Build.props decision or an idiomatic suppression), not 84 independent debts. Decide it once centrally rather than file-by-file. (Every occurrence still counts toward the score and metrics.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Callbacks/AutoCallbackTests.cs"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"d886d00825d94b7720e26d939b23d7b48e7ea9c60b20a7b7cb0b41c0844ee963"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined StubComponent has no generated factory \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Components/DivScrollTests.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"b11a263586061a38d50e4b003d419f8d5d84a7ca766866cfb2c10b523e2daa82"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined StubComponent has no generated factory \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Components/DragDropTests.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"984d218ab952643f9502d6b3652e02ef4634dfd794058face0fcad517607dad1"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined StubComponent has no generated factory \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Components/ElementDomEventsTests.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"af4008890d75342a929431e06a7f36da8e9a3e3482c2796a8dbefd001f55bd11"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined StubComponent has no generated factory \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Components/ElementDragTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"344ec08abd84c7a51107ddc190d080818917bc65dfe78426700a498889c7ceda"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined StubComponent has no generated factory \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Components/ElementKeyboardTests.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b74b4c4cac74bc33bc2154ab382e262b5e9ee8203ae7b5dadb288cdcc77bda1"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined StubComponent has no generated factory \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Components/ElementToggleTests.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a2bc493ed01962d85ec4035dbfa269bcaf5026842d7beb870dfa8b954fe2576"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined StubComponent has no generated factory \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Components/VirtualizeModelTests.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7c3e391d013d01e4c7f80c5a9e2b6d45719a4164c4e463abb03c5f24f01e989"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Forms/AsyncFormBindingTests.cs"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ba39e965da3411f7e0bbc69da17d40ac5e472438640b3b9bb96eb3752dc60d4"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Forms/RaskFileDispatchTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad1cdc7c5a7ea69ac4fc773af8a555101f7c63b23ffb5d56864ceac8e4530c1c"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/CrossParentKeyedMoveTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"44c3a586327d0e352fa5c9c3c4fba0d9c8d918d6b6cf1ed9b99cd4933a77b8ed"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/MouseModifiersHandlerTests.cs"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a8b9005093539d8eeef6f1ef4cd7a5df90bc7f7d7741a33629a44cae766c8a2"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined component subclasses have no generated factories \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/CleanSubtreeReplayTests.cs"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"300ea0499ed26cf56a674a1691b9bfe36303b1759e846095aaa0c0a38d415e43"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined component subclasses have no generated factories \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/ExternalStateInvalidationTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"5db52545d17d6a153252241d616534b4567a7673ae10b78289e446b67e261bcb"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined component subclasses have no generated factories \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/OpaqueSubtreeTests.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f2d586e4eaf277ea22685591e7ce5eeaf2728d9a9fb47bd3489aac0018c1862"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined component subclasses have no generated factories \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/StableHandlerIdTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab730873ba45d0dca3df9e9002e724f792f5bf7e2c6e68e7d4d916e313c53ff6"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined Component subclasses have no generated chain entries \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Live/RaskPrerenderTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"c60a8a1c38bb53b5122469c1e12b1eac01955de0b9353236d5414da8a1260d2a"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined Component subclasses have no generated chain entries \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/WebSockets/MountNavigationTests.cs"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"f36970d10c99d27583bd24c446f08ebd8fe184fc3a9648954f99e3e18518d257"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined Component subclasses have no generated chain entries \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Wasm.Tests/Hosting/PrerenderBatteryWiringTests.cs"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5a201c9811c0a098b96faf9b8ef61502d54ca63f88fca006f481ff160585d7c"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined Component subclasses have no generated chain entries \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Wasm.Tests/Hosting/WasmPrerenderTests.cs"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"11b7cbe3c4b0e2c7b76a53038d4f67cd6b9e359fc860112c3a18eda9612410b6"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK019 // test-infra app predates framework-managed \u003Chead\u003E \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Authentication/DeferredAuthNavTestApp.cs"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e8544ca579b47d0292441424b5aff3fb132ccc2f6e99974420c2dd31ae4ae68"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK019 // test-infra app predates framework-managed \u003Chead\u003E \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Authentication/RevokedAuthDispatchTests.cs"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc7dc47ae3d603280a17aa65ec9c0414d7039b1a7a47773eb3eb289634f2a7f7"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK019 // test-infra app predates framework-managed \u003Chead\u003E \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Authentication/RouteGuardTestApp.cs"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"efc81b390842d295474aa54f891adb295c5ea40aab2c948bcda9e2cbf3537557"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK019 // test-infra app predates framework-managed \u003Chead\u003E \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Endpoints/NotFoundStatusTests.cs"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"7377c6f7c659afd2fa51d6bbe825f7cb20546d5d6a81afe27512520261bc6599"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK019 // test-infra app predates framework-managed \u003Chead\u003E \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Infrastructure/CheckboxJsInvokeApp.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b06ef233871db22bc2a7a4c8be4414d27b1750ec435b7d88518c05430cfc0f2"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK019 // test-infra app predates framework-managed \u003Chead\u003E \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Infrastructure/JsInvokeBindingApp.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"78e49d7515a30c569e58ab0805cf33d90194a203df05663fda97217a2b02dc40"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK019 // test-infra app predates framework-managed \u003Chead\u003E \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Wasm.Tests/Session/DisposalTests.cs"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"901d4f3829d73be9b02103706d8bab087b9f10c786317d09d0680dce5d24238c"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable repeated across 33 files: The identical FileScopedPragmaDisable (\u0060#pragma warning disable RASK019 // test-infra apps predate framework-managed \u003Chead\u003E\u0060) appears in 33 files (33 occurrences) \u2014 a single repo-wide policy (e.g. a Directory.Build.props decision or an idiomatic suppression), not 33 independent debts. Decide it once centrally rather than file-by-file. (Every occurrence still counts toward the score and metrics.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Authentication/SignInTestApp.cs"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"d82ed8edce54f3295933ca169efdc3483eea4cf31a06324e30511cd37f2296d4"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test renders the demo component directly as a root \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Site.Tests/Demos/AuthorizeDemoTests.cs"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9be50bde760c84c398bfde98bcf87cc9e8ad20fa77453bfd65227ad75fbc6c5"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test renders the demo component directly as a root \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Site.Tests/Demos/NotificationsDemoTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"6616329185d1c1578f5926df185ec44f39984f0981b0259734d11ce1c43a3a29"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test renders the demo component directly as a root \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Site.Tests/Pages/KeyedListsPageTests.cs"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"193951d9deb516ca8c5839205ce22a723cd2359fb4f7d38a1e592d020ccf755e"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined components constructed directly \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Testing.Tests/MarkupTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4735b65ce0da212d6b858fb2d04acbdee0c39f01da282ec5bd670aaef7c74f3"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined components constructed directly \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Testing.Tests/RaskTestFactoryTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1953569d0718acf507a94a3f4f9cc6e2e2f0710edaff468e13c78087bc166874"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined components constructed directly \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Testing.Tests/RaskTestMountTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"32574d6c6a236e969b7ec564aaff7a0955ceed2099d339f2602e1fe6e4ddbb79"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined components constructed directly \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Testing.Tests/RaskTestTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"472f8e2486edc6059b77e0b2e6638080931cbd949409a34088d6f96dc03917d1"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined components constructed directly \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Testing.Tests/RenderedComponentInstanceTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"52f7a5a48a6364b28eeb9e07a7cfee9f65a94ac8b9e0c81ef16f02a41d4508ca"}},{"ruleId":"D17","level":"error","message":{"text":"FileScopedPragmaDisable: #pragma warning disable RASK014 // test-defined components constructed directly \u2014 the disable has no matching restore anywhere in this file, so it does not end with the construct that needed it: it runs to the end of the file and silences the rule for everything written below, including code added years later that nobody weighed against it. Close it with the matching restore directive immediately after the construct it covers \u2014 that alone turns a standing exemption into a scoped one \u2014 or fix the cause and drop the directive entirely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Testing.Tests/TestJSRuntimeTests.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b27e8834432d40af28a33257e548048344ba24800adfe40fb7cb29d6fe11b3d"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Wasm.Tests/Rask.Wasm.Tests.csproj"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfb21d86cfed5c93b0535b3b0c51ef48f2df03fa832a69758f2105c56e906f0a"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Ui.Tests/Rask.Ui.Tests.csproj"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac1c2cb0906a9f21ec064a77293a2b1f83c79bb92438a13b1b693bc92a822c92"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Tests/Rask.Tests.csproj"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"75322f1dfb39261583c7cbc5025171aaec2618df793ff72a080b49890f8dee6d"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Site.Tests/Rask.Site.Tests.csproj"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"b142faa39ae515c5cf28075e6cee6de1ab7520848606b40c6ef8f2b1f37f6fb2"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.Tests/Rask.Server.Tests.csproj"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbdefccceb4abd568979a25c2179d4a96c6fc5e06d72823b4651d19ab5cdb52a"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.HotReload.Tests/Rask.Server.HotReload.Tests.csproj"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"face58d8678a4b8fb112bb832d55b7cf06d0160dd286afd46173d5a0a8e5f7e9"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Server.E2E.Tests/Rask.Server.E2E.Tests.csproj"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"66a183ce0f038442e51eb50bfeaec6231e592fded52f49f2e2550ed739c699ec"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RASK014 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.DevTools.E2E.Tests/Rask.DevTools.E2E.Tests.csproj"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"09ae1cdaaea3b4ed1c66906973e4379a6803919f1bc64886b4cedffd4c207e45"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: IL2104 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.DevTools.Fixture.Wasm/Rask.DevTools.Fixture.Wasm.csproj"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c95ad3b9a3cda791182fe7e68205e7271aca8deba8d67278d724f4bffa25a03"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: NU5128 \u2014 this warning is switched off for the WHOLE project, including builds years from now. It is raised by the build itself \u2014 the packaging, restore or SDK step \u2014 about the project as a whole, not by the compiler or an analyzer at a line of code, so there is no call site to narrow it to and no per-site directive that could carry a reason: this element is the only place the decision can be recorded. Say WHY here, in a comment on the entry, or fix what the rule is reporting and drop the code from the list."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Tailwind/Rask.Tailwind.csproj"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"4422d8d001734d852d24347b940733baf034c5dd7dfde6bdd8b4925089246e58"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: SYSLIB1100 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/Rask.Jobs.csproj"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c4835c6692005ce19765a6f1a4c47a5ce8574e1cf71e34ffc46b6de6eb29a00"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: SYSLIB1101 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Jobs/Rask.Jobs.csproj"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"2036a766b87ea2e8e33ccdd9def1b7eec5680f9e96c18073f31ad18946bd76d5"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RS2008 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/Rask.Generators.csproj"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ec8901293567748554766dafcc571ebda41a60d49151d12bb8478b41c554f48"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RS2008 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators.CodeFixes/Rask.Generators.CodeFixes.csproj"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9f5a3c5a07c91e5cf241275ec87a6caf493c2cf2a6092f7655d0711a6d8242f"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RS2008 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Batteries.Generators/Rask.Batteries.Generators.csproj"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e68830ea0fcc41aede9e2730a7168190c4f1162b245863752d4c12ff0acbab6"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: RS2008 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Api.Generators/Rask.Api.Generators.csproj"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5694147cee29fe5a1382b8fb86cf58b4a1ecca0274b47fb93785f6fc8891c2d"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: CS1591 \u2014 this project generates an XML documentation file as a build output, so its documentation is something it PUBLISHES to whoever consumes the assembly, and this entry switches off a rule whose only job is to report that documentation missing or malformed. The two decisions sit in the same file and the quiet one wins: the documentation this project ships has holes exactly where the rule would have pointed, no build says so, and the people who meet the gap are downstream \u2014 in their editor, at the moment they are trying to use the member. Write the documentation the rule is asking for and drop the code from the list; where only some elements genuinely cannot carry it, narrow the suppression to those sites and give each one its reason, so the rest of the API stays covered. If the documentation was never meant to be consumed, the honest fix is the other line \u2014 stop generating the file, so the project no longer publishes something it is choosing not to check."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"Directory.Build.props"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dd2c0f1bc6fae94c476742a893c35de7153943503c0bde5fd83e9da0475b18e"}},{"ruleId":"D17","level":"error","message":{"text":"AnalyzerSeverityNone: RS0026 \u2014 this rule is switched off for every file the section matches, in every project under this directory, and the only record that it was ever switched off is this line: nothing at the sites it would have reported says so, so a reader of that code has no reason to look here, and code added years from now inherits the decision silently. Fix what the rule reports and delete the entry, or \u2014 where some sites really are legitimate \u2014 leave the rule on and suppress it at those sites with their reasons, so it keeps protecting the rest of the tree. If the rule is genuinely unwanted here, say why \u2014 on this line after the entry, or in the comment run directly above it: a comment that only repeats the rule\u0027s own title is read as no explanation at all and leaves this row in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".editorconfig"},"region":{"startLine":272}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a6048331616b405418835b97daaa1a237bfcf9e49506906da7cca381c121a27"}},{"ruleId":"D17","level":"error","message":{"text":"AnalyzerSeverityNone: RS0027 \u2014 this rule is switched off for every file the section matches, in every project under this directory, and the only record that it was ever switched off is this line: nothing at the sites it would have reported says so, so a reader of that code has no reason to look here, and code added years from now inherits the decision silently. Fix what the rule reports and delete the entry, or \u2014 where some sites really are legitimate \u2014 leave the rule on and suppress it at those sites with their reasons, so it keeps protecting the rest of the tree. If the rule is genuinely unwanted here, say why \u2014 on this line after the entry, or in the comment run directly above it: a comment that only repeats the rule\u0027s own title is read as no explanation at all and leaves this row in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".editorconfig"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8b583350f696b7875b36e055f29566f8c2b42b75923f9c986382b08f4fe86e6"}},{"ruleId":"D17","level":"error","message":{"text":"AnalyzerSeverityNone: CS0108 \u2014 this rule is switched off for every file the section matches, in every project under this directory, and the only record that it was ever switched off is this line: nothing at the sites it would have reported says so, so a reader of that code has no reason to look here, and code added years from now inherits the decision silently. Fix what the rule reports and delete the entry, or \u2014 where some sites really are legitimate \u2014 leave the rule on and suppress it at those sites with their reasons, so it keeps protecting the rest of the tree. If the rule is genuinely unwanted here, say why \u2014 on this line after the entry, or in the comment run directly above it: a comment that only repeats the rule\u0027s own title is read as no explanation at all and leaves this row in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".editorconfig"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"72b5a3a24eb445208a2e47d74b90b40592ff451026eec06f4eec72b16fbc821b"}},{"ruleId":"D17","level":"error","message":{"text":"AnalyzerSeverityNone: BL0016 \u2014 this rule is switched off for every file the section matches, in every project under this directory, and the only record that it was ever switched off is this line: nothing at the sites it would have reported says so, so a reader of that code has no reason to look here, and code added years from now inherits the decision silently. Fix what the rule reports and delete the entry, or \u2014 where some sites really are legitimate \u2014 leave the rule on and suppress it at those sites with their reasons, so it keeps protecting the rest of the tree. If the rule is genuinely unwanted here, say why \u2014 on this line after the entry, or in the comment run directly above it: a comment that only repeats the rule\u0027s own title is read as no explanation at all and leaves this row in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".editorconfig"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"257ce817baa5d94c069773a12ca1a686a30f8dda2264f84535f977f4a4f9da64"}},{"ruleId":"D17","level":"error","message":{"text":"AnalyzerSeverityNone: BL0016 \u2014 this rule is switched off for every file the section matches, in every project under this directory, and the only record that it was ever switched off is this line: nothing at the sites it would have reported says so, so a reader of that code has no reason to look here, and code added years from now inherits the decision silently. Fix what the rule reports and delete the entry, or \u2014 where some sites really are legitimate \u2014 leave the rule on and suppress it at those sites with their reasons, so it keeps protecting the rest of the tree. If the rule is genuinely unwanted here, say why \u2014 on this line after the entry, or in the comment run directly above it: a comment that only repeats the rule\u0027s own title is read as no explanation at all and leaves this row in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".editorconfig"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd0472c210acb89af2af19a002a1bb0b05777eedd4e1d8ef785dd697b9f773c7"}},{"ruleId":"D17","level":"error","message":{"text":"AnalyzerSeverityNone: BL0016 \u2014 this rule is switched off for every file the section matches, in every project under this directory, and the only record that it was ever switched off is this line: nothing at the sites it would have reported says so, so a reader of that code has no reason to look here, and code added years from now inherits the decision silently. Fix what the rule reports and delete the entry, or \u2014 where some sites really are legitimate \u2014 leave the rule on and suppress it at those sites with their reasons, so it keeps protecting the rest of the tree. If the rule is genuinely unwanted here, say why \u2014 on this line after the entry, or in the comment run directly above it: a comment that only repeats the rule\u0027s own title is read as no explanation at all and leaves this row in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".editorconfig"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a3ef2c822cc680d2a276cf18ddb5489ae1ce1f208c3a863b606b5228b2f9dae"}},{"ruleId":"D17","level":"error","message":{"text":"AnalyzerSeverityNone repeated across 16 files: The identical AnalyzerSeverityNone (\u0060CA2007\u0060) appears in 16 files (16 occurrences) \u2014 a single repo-wide policy (e.g. a Directory.Build.props decision or an idiomatic suppression), not 16 independent debts. Decide it once centrally rather than file-by-file. (Every occurrence still counts toward the score and metrics.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/wasm/.editorconfig"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f22bdd024cc6c910bd3a20c18f5abf8b5a1dd6175ab8300b090d179340d0c9e"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no installation or build instructions: The install section is present but terse: the one-line curl installer with prerequisites noted as optional (\u0027Prerequisites: none. The installer adds whatever is missing\u0027) and a brief add-package command for existing projects, but no full installation/run steps. Expand to include how to set up the .NET SDK/wasm-tools/workload, run the one-command install, and verify it works (dotnet --version)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fa6bfcd5c6ae231d1b8ee99bced50b832d1f61cde9da6cbb533467b879a57db"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no usage examples: Usage examples are sparse: a Counter component snippet is shown but no runnable \u0027how to run it\u0027 example for any of the four front ends. Add a short runnable demo showing how each front end (React, Vue, Svelte, Blazor) gets started and routed via Rask."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1355eb4e127a4bc9236772ce1c46f09510aa9286e7a06d1e47f308229df19049"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no installation or build instructions: The README describes how to run the Solid front end (\u0060rask dev\u0060) and add a message, but it omits any installation or build steps for the ASP.NET host. Add install commands for the ASP.NET project (e.g. \u0060dotnet new\u0060), the create-vite scaffolding, and the required Rask client NuGet reference."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solid/README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"79764237c501db610191a68923b0af657a30ab3cf7cd5ae83217272c1dbab501"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no installation or build instructions: The README describes how to run the React front end (\u0060rask dev\u0060) and add a message but omits any installation or build steps for the ASP.NET host. Add install commands for the ASP.NET project, create-vite scaffolding, and the required Rask client NuGet reference."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/react/README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"82531de9920b88277528bdc71fcf591ff62683cd61c8257a325c2eba32461650"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no architecture or design documentation: The React \u002B Vite README mentions Oxlint plugins and a recommended type-aware lint config but does not link to any architecture or design documentation. Add an \u0027Architecture\u0027 section describing the template\u0027s plugin ecosystem (React, SWC/oxide) so readers can find it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/react/client/README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"96b5e5422a5065228f4865006fc6b3ef55c11c3740b330005a84fcf909776665"}},{"ruleId":"D20","level":"note","message":{"text":"No ADRs found: No ADRs found. No recognised ADR directory (\u0060docs/adr/\u0060, \u0060docs/decisions/\u0060, \u0060adr/\u0060, \u0060docs/rfcs/\u0060, an \u0060ADR0001/\u0060 folder, or their siblings) exists anywhere in this tree. What was searched, so you can tell an empty log from a search that missed one: every directory under the tree (build output, dependencies and VCS metadata excepted), for a document that is either any non-index page inside a recognised ADR directory, whatever its name and however deeply nested (\u0060docs/adr/use-postgres.md\u0060, \u0060docs/adr/2024/0001-x.md\u0060); or a file anywhere whose name is ADR-shaped (\u00600001-use-postgres.md\u0060, \u0060adr-012-caching.md\u0060); or, when neither turned anything up, a document carrying the decision-record signature (an \u0022Architecture Decision Record\u0022 heading, or Status / Context / Decision / Consequences as section headings). A decision log that clears none of these \u2014 unnumbered files outside any recognised directory, without those headings \u2014 is not seen by this check and this row is then wrong. If that is your case, say so rather than renaming anything; otherwise, consider recording architectural decisions in \u0060docs/adr/\u0060."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d2bea044ff79d7d275f5a91a6e2f548586178eaf480274c33960ad020c854631"}},{"ruleId":"D22","level":"warning","message":{"text":"Ambiguous overload resolution for SetAsync when both options and typeInfo are provided. The API exposes two overloads that differ only by the presence of JsonTypeInfo, but if a caller wants to specify both, they cannot do so without creating a new overload or using a different method. This forces users to choose between providing options or type info, or requires a third overload.: Add a third overload: SetAsync\u003CT\u003E(string key, T value, JsonTypeInfo\u003CT\u003E typeInfo, DistributedCacheEntryOptions? options, CancellationToken) to allow specifying both, or remove the options parameter from the typeInfo overload if it is rarely used with type info. (signatures: Rask.Cache.Cache.SetAsync\u003CT\u003E(string key, T value, DistributedCacheEntryOptions? options, CancellationToken) | Rask.Cache.Cache.SetAsync\u003CT\u003E(string key, T value, JsonTypeInfo\u003CT\u003E typeInfo, DistributedCacheEntryOptions? options, CancellationToken))"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"24fe89136cd864695eeffd2433aa56f2eb7c53cbccd5abd35d9eada4d0385364"}},{"ruleId":"D22","level":"warning","message":{"text":"Same ambiguity issue as SetAsync. If a user wants to provide both JsonTypeInfo and DistributedCacheEntryOptions, they must use the second overload. However, if they only want options, they use the first. This is slightly inconsistent with standard .NET patterns where optional parameters are often combined into a single signature with optional arguments, or distinct overloads are clearly separated by purpose (e.g., one for serialization context, one for caching options). Here, the separation is by parameter presence, which can be confusing.: Consider consolidating into a single method with optional parameters: GetOrAddAsync\u003CT\u003E(string key, Func\u003CCancellationToken, Task\u003CT\u003E\u003E factory, JsonTypeInfo\u003CT\u003E? typeInfo = null, DistributedCacheEntryOptions? options = null, CancellationToken cancellationToken = default). (signatures: Rask.Cache.Cache.GetOrAddAsync\u003CT\u003E(string key, Func\u003CCancellationToken, Task\u003CT\u003E\u003E factory, DistributedCacheEntryOptions? options, CancellationToken) | Rask.Cache.Cache.GetOrAddAsync\u003CT\u003E(string key, Func\u003CCancellationToken, Task\u003CT\u003E\u003E factory, JsonTypeInfo\u003CT\u003E typeInfo, DistributedCacheEntryOptions? options, CancellationToken))"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a8bb3b14d307e7542f77d588ed8c696c1fff66cead5c3a8531ce97852b011986"}},{"ruleId":"D22","level":"warning","message":{"text":"Same ambiguity issue as SetAsync and GetOrAddAsync. Users cannot provide both JsonTypeInfo and CancellationToken in a way that distinguishes intent clearly if they also want to pass options (though options aren\u0027t in GetAsync, the pattern is inconsistent with SetAsync/GetOrAddAsync which have options). More importantly, the existence of two overloads for GetAsync where one adds type info but no options, while SetAsync/GetOrAddAsync have overloads with options, creates a fragmented API surface.: Align GetAsync with the pattern of SetAsync/GetOrAddAsync by adding an overload that accepts both JsonTypeInfo and DistributedCacheEntryOptions, or unify all methods to use optional parameters for typeInfo and options. (signatures: Rask.Cache.Cache.GetAsync\u003CT\u003E(string key, CancellationToken) | Rask.Cache.Cache.GetAsync\u003CT\u003E(string key, JsonTypeInfo\u003CT\u003E typeInfo, CancellationToken))"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fd28f6c4523a16b36141373d7bd3c98c91bac10ff4212d91293f56959ce66a73"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.RegisterAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e8cbc95c56fcce274ccf8ee8b1758dd14d26fa6d8912234cf0a16d63c055fc0a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.SignInAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"007b93df339830a88296064d5de2c598c9617707c1f9e6aba992dae86065d03b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.SendPasswordResetAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"dbc5b852482d5204b8c6865ad2a80648873793af2cc329628453e9a28f9a104c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.ResetPasswordAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"28360aa90dc4e1498e57fe03108ecda3b89d9009acf339322c1ae0f2efb1c7bc"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.ConfirmEmailAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"75baf50c88dc15ec0de910f2d2263ca8098fbaac20a7ec76204ece606e3c0654"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.AddPasskeyAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e27fb0d11bf187a493d27786b95df7b427b2721d6469b3de77526afb551a4cf4"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.SignInWithPasskeyAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c953196a677fcb69f9774382e11d4245ed043d5815238bc3f8247c3cb12f3268"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Auth.Client): AuthResult (context Rask.Wire) is exposed in Rask.Auth.Client\u0027s public surface via BrowserAuth.RemovePasskeyAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e6698aaa8cd851c1359513dc061650a57b3cf86224cdf1e45fe1ec07f31c0577"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.RegisterAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"76a05774051bacb2f9834de178d6aba8775a2ed4fcb6ec607abf57f1abc446cb"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.SignInAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7be3a5a5ecd0f7464470c6362e5c9823ccadcba2e6b5d7601ea87f93a92e8f82"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.SendPasswordResetAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"75bbc535b8d09d405bc1831997013dba9e702f918d8f58363513b60a72e9d56f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.ResetPasswordAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"af07038f2e99444b2894b8b5034a2a9a83261f7a4034209c97681c4ab465bd3c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.ConfirmEmailAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"bfa623815d6005184454e52c81ebc10efd75642bf7705c8b9a23a727461c8c62"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.AddPasskeyAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ce968c5dd398332d3f297714213cdbc803bc1e9d03ada13749833c9bf7c617a0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.SignInWithPasskeyAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6c66b255bdefefd272aebaa774a06e9ea134601078add44bce77765e22b0522c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type AuthResult (Rask.Wire \u2192 Rask.Core): AuthResult (context Rask.Wire) is exposed in Rask.Core\u0027s public surface via IAuth.RemovePasskeyAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"060a66d5fb66d1c3401d7ee0bef80519c5df28c9beeeb64b64ab4f5139f65037"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type WebAppManifest (Rask.Core \u2192 Rask.Server): WebAppManifest (context Rask.Core) is exposed in Rask.Server\u0027s public surface via RaskPwaExtensions.AddRaskPwa \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"3b2c53ce442bb2d5ec3c4875c3058811a087ec839ce53b1e7ac1262b4bc1a680"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Site): RouteUrl (context Rask.Core) is exposed in Rask.Site\u0027s public surface via PageMeta.LinkTo \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"081ffc92c41a3d1c901fafea9263e7b557d85da107dcbfb83f97ebe67c7275f7"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type FieldIdentifier (Rask.Core \u2192 Rask.Site): FieldIdentifier (context Rask.Core) is exposed in Rask.Site\u0027s public surface via UniqueUsernameValidator.ValidateFieldAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c09cb97abc5067999d728a950e4a3c2c2e8140f465b014f32368bca6f48f4bb1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type FieldIdentifier (Rask.Core \u2192 Rask.Site): FieldIdentifier (context Rask.Core) is exposed in Rask.Site\u0027s public surface via SlowTitleValidator.ValidateFieldAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"56066cf9802bc6d3507f70302ab9c58890877d15afa8dcc0c57f2ae3f754df26"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PendingDownload (Rask.Core \u2192 Rask.Testing): PendingDownload (context Rask.Core) is exposed in Rask.Testing\u0027s public surface via TestDownloadSink.TryConsume \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ff1015fc85c860e814a38edb1b65fccafc29815fce93df7ea7d18f6eaea84c68"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiAccordion.OnOpen \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7290aed585941732b837cab8e9782c38f1155e36882c64c7a804a3161c4ab31f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiAccordionState..ctor \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"567631d31215772c611c34764ff8f9964a84164290ddffc437ff282fcbe037e8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiAccordionState.OnOpen \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f5abba598bd8a8cbf41491a592e34d3220dbce0b442aabe12fb08521d39b6efd"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiAccordionState.Deconstruct \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d16e611b45875562133950aecee46d90d02c897a00efe7903b0c22654ae51c1e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiBrand.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fdb7fbdedcae301ceb901c60aca265e246ad0b3e58ae3dd9d797c1d7b5faeaa5"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiButton.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c2374549a8f89a412a230b38d8a89d6012a295caa4865fcfb616dcf33500586d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendar.OnMonth \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a7400596a5b60e2ac8137ebf9c034ad4e4d7b34a4d0ce49aa51fc63c3215c539"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendar.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"06521e74062aedee1684bb77730acf78a5ca252b29f990487008ecbd4e4f9dc1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendar.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"93b9b40dfefca2fd278a96e570d0210f5d4e668dfa69eaae4a60d8c147a52997"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendar.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"bdb7e8a385780bdad0f04b37c2f455b2ac7e2ce22693064c37cecc5ad405f636"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendarMultiple.OnMonth \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9ab526be846c56ca99190a24521b62e4556815a52fbdacdcc10ee89b682748db"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendarMultiple.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8a5c0ee989f8854e91bc894d006135a0e23d9b3dc86b642f5e8e8c84dcfea015"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendarMultiple.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"1fbd716bafffe32fd42ce03734887ad3075fcf7e341c8c136df180128f147a55"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendarMultiple.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"802a1d1f8c4f8e3b0d1643493d0369aeb4f70937f3836ff7476b53697eafb092"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCalendarRange.OnMonth \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d5c5b56b47bc4e0627c6f4dbbf3b2104549d2cc8842da3ad6e5a3c7079bba2f1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCard.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f3dc4991723914cf32e3f153b3abb7e484c76ea7fd83498aceb9435ca7ecddc6"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCheckbox.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7695ff85a79e1343224abd76c469c04d3e33bc0f6090f5f54d5098e47bd7d59d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCheckbox.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9cf2b83ceb2761a7becb783c820f53bb9b03ccf858c2f41e2f3ef9df31c9ab9f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCheckbox.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"707245e3259e8b5698cf8c46057f7163313b9bdb01aa109d2c976ccc5d7048cb"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCheckboxGroup.OptionDescription \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9797eca2d2166ea03817fa506c1287213cf4e25db5ba7dc4317b03b50bd64055"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCheckboxGroup.OptionDisabled \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0beb77888c596319c1ac1447162e28fb47966be82841e1ea5fa094ffd411325f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCollapse.OnToggle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9e085a6f34ca47707aa7c0bcc1e5b5bd817691c0426addc99dd2f12796900bea"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiColumn.Value \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a4a5425ec27f2190d8d5557d74202e5d36ace9e04a9e4379212b08eacfab4d27"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiColumn.Cell \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"73505e0de4ee93650c98458be1529e8b114255d8c4b2009151d19d292a34e1fb"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiColumn.SortKey \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b4976f281908c1aef38f389c9475ba08341c86fb9ae7d12903e0f347eaa8af7b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiColumn.GroupKey \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cc1fd9e9574a536a2b520248b0fef3265607ac4e8e451c6a27b0e32ae5605db6"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiColumn.GroupHeader \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e295038c5ce2bb7af47d81807ed7d894b7909e609e2650802245e7e572c7932f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiColumn.Footer \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cdb6eb9681f7c5d53837d9a6f7945e9605e0a0420d7aad2caacad6f2b315472c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiColumn.FooterCell \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8ba4c97efcd8e65582e150a32ff69de19e611e2f32079f5af8647bea5e2a0dee"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiCrumbSwitcher.OnSelect \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"23b07e4c11e21764c2729d1437651ecb7e85933da531848a348d7a3a36ed2377"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.OnSelectionChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7ac07dc5571d8f9b533b963184f01d675e44d4dd6e39cae8fde0d87a57d10dd4"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.Source \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"70c48c77b8b28d243393a4949fc41240096c6bcbbf36c1913786ed8c8bd550f7"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.OnPageChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c7ab6da477e4784e21d1f189c9378aa764b3785739f328a7f4d9f531dff8c6bf"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.PageHref \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"50f5655b82c650614267d1793bf7bcf5e846e0d07a5274db5bf5a014e64d02eb"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.Detail \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"567c32debc38ac746aa5ccb0c9e9d035c43d591bb06f496fb51ccfe4dd223e4e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.RowClass \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b75347a39eecdcc522fd37edf5045f60e713b33f35e6e332f74e82002b0f889f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.RowTone \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"22d88d428f3696dc477b221c83a6368204e673d89f11431989875c753c3a8bdd"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.OnRowClick \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"122fe7bcc06e3156ad5c8a1256023fabfe1bbd971eb6d6e23c066c112c2800ba"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.Card \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cc163eeb86a151f7ece61c79145742dc3aff7251bb589f9345d63647b8eed446"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.OnHiddenColumnsChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"66869dd82c4321595aeec5e2ac9d268de01ef59c5bb6cb37222306e7d1da3921"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.OnColumnOrderChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"bc063e1278b91480f30d65584c84abbc2d235f3c5f29ca62ba6edbd194e0f579"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDataGrid.OnGroupedChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"83039af2e790d2e47d731435af63a51f4f36c2569dff8b6c7f94e226fc22644d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiDrawer.OnToggle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e36962f20e14140a79657cd10f8ca856c1b153084a50512b44ea4e82770a4b15"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFileInput.OnFiles \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"20ddac610baad4f4c0659b12b025ca66ad971e4a5236f7e6b1c28af564014ff7"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFileInput.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a3736ec62fe1bd2a547c237adfbda8236b62b34720bba5a3bf72308bd4bd43d2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFileInput.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"166cfb53ee148a0b3b8975cb60af8f3be1e8f56cdb20dcecf1f0d132f881706c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFileInput.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7e033c08ee2d278786bf70801fcda3e3500894f35f9f705b0a7dbb046c80951c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFilter.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"78a2542cae8badfe26e0d5a86a3063277f55155a83dacd65c6e3ca010dc8f4a3"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFilter.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"87fbf283b64ab56330f6ad1440fe3ea931ea06d51f42787373a3f20ff709ee26"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFilter.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0b443261c87418f25de31f0a05db3dbcdb93fe4d93f2b3cdeba2b90c9bf9064e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFormField.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5e256d051ac589f0419c5001ff6e9c25b2321aefcd13f8d9f632a7b4829f6aaf"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFormField.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"212c6313cccdde388d4c381b1bbfc21a6ec375f8f6b5a2fb9fafae4a78cb10b9"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiFormField.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"61c8219f33d0c0ae4eed0baf524742031a3274685c15941b51a09784b9205eed"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiInput.OnInput \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7f06da42a2593e4104514ad7b557379500cef058a2d271716f341086f6b45270"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiLink.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c8096d7c6489d35b38454680d9b964539cdc95c708dceca977bf75038940b6e0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuCheckbox.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"47bc6b9977be523fc3a84dbf7e6544a977f747d7e396d82cbb03e2769b6a3df0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuCheckbox.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cb66a335ad92c74a31b1b85ec8eacdf35a8ed08afcb8a205277605413e0b91a5"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuCheckbox.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"88f06d33be6664d3b659d5d5df6223113ccd383582fe17221747404495f83090"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuItem.OnClick \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"623486c32099d216bb8ae65b4766fcb38ef86a484dbcdaafeef9b694b3fc7531"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuRadioGroup.OptionDisabled \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e2b4ed9f501f19c1dbe8652474496fc6fb1ee620b562297deb3a08c17f4c1147"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuRadioGroup.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"538c4b3fa797565f15ce89fcad9ae6449acceae0ab4b1a4780d6db5d178a0162"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuRadioGroup.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0ae318f3e8ff0b4c2708a4609302a27d836c5dedff568865cea6f11ea2c907f0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuRadioGroup.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d7f7b126dda27394d49d4b7a89303dabed82202d4f2970b4dad14995614cdad8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMenuSurface.OnToggle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a7e23b6b780c3e2ef4e8e21166aec6132816db82561fb0385b8facb3e555beb0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiModal.OnClose \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f59c0a7267dbb4ac81d68c7ce9b324b9b69a0ec150a592cd64d3f5985c327847"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.OptionDisabled \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8e6e6557f54caf4f67819cf4b62cf32b9ab1496091c82eb4905c9b8f250fb1f0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.OptionGroup \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"28b6d8ff0ac4ca0ed1ef74ed6f528685141313d60a08c5170f9ef4f5e4a11ffb"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.OptionTemplate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0f7a425a7b728c8bc300b7a0d1f7c27c26aac419e0f6b4c52b76dddc9f47c91e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.ChipTemplate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f2c6edab5b672db6c40ea205d5141765707bad47e2b4a0dc48de59cdda504d20"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.Filter \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e17e3dd97bb75d365ee00683755b2dbec70bcd223a526d11db830d30f65a52f8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"43c16a1e906f06b5a327141c055b57524d8e3cc50f83d85b678ba4135b45c799"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5ec4c73151f2867988d64db87defc0971ab464cb804b001c5729cdd88ff09663"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiMultiSelect.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d71c85b2a138bb3d3fc4aa2a516ef9a0e1033f8885feca61a4b1eec282187a39"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiNavGroup.OnToggle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"337b68c8abf312c939cf8e59472cfe4e1e30d290a022aef3d63e53f70fdb2230"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiNavItem.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"45d0f289f7e89530fc247ff5421e3e7883b7b2e790c136a2f88c16e6d3fb98ea"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiNavItem.Match \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"724b3d683cfd8c7f2c0169f2a8d3921fda00e8a09c9d99ff212b2a52f1424c7a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiNavTab.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"3e7035b85a891371d4166921f30e8b3b42b8a0cdfcda2513ad358e51bfe64102"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiNavTab.Match \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8fe7b397b2cdce45097248c92282e3ab4ef7e0bb25316365a6e6d140fb3cd836"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiOtp.OnComplete \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5329e482ef2f76d85140cd78a53aa382c4ded473cb8538b01d9de54f2afbe68f"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiOtp.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f5213f8a7f474f5d3bd3002c6837e78bb71b3c3dc98d29d0857007db5eb07477"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiOtp.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f7eafe90b949f210c656fcb9472b0d591d7349cb8e9762ae7ddf157da4b8407d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiOtp.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"3ecf3694ebb0dd66d9ed1d8c15350ef9c149d3dacbd94dededd3853699c867da"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiPagination.OnSelect \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ebe35d5d70cf85cbe46065d84c75281a594e2647eb0de274bf9c30dc9e5b1631"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiPagination.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"26d6136d3b014da33974bdcd4506fad11b2d779e8abcc40a219d20c632d6c5c9"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiPopover.OnToggle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"2651edd43d06b4f5a7837b731417c5742f494631cbdbd7843c38a7de33599526"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRadio.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"845a5e004d996044c8d4ea230aa5b8ac36da211d0772544cde06f254228c49ba"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRadio.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"490751b5c0dcdf0cbf0103bd3509749980ff421356cc3b6a84f6a5f57e519c4a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRadio.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c079596d6435132a9cf3b4ba49186371b473385bcd5a6ff0cd1817d2761ea4d0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRadioGroup.OptionDescription \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f7c36f5331bdfd5b75dd0c7cedf4814805ee7e62419722834a45bcf76c20104d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRadioGroup.OptionDisabled \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b580f1bc8cdf8b245f3e3ed89fe60a2ffcd3f657d1cd6987ac739a3f5f07d52c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRange.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c2cca5c664742ccb338177c139bc300d6b1a98b2ff85d2a77a04b15391458cb8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRange.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"845e7f555f6e0a50ca06dffca83f122ef4210e6d8f50032b209751df77d64209"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRange.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"faa56e70dc03b369dee9ac474e769b85b29cf85dd2a790c997a8c2774d329495"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRating.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0b40f1d9b347be4984ffce17791bf926ab5e170639152a6d4607d1848543dc7e"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRating.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c25e0cde65cd708b075920725ab7e83836e0efcb2fedea97670bbed4a70868e9"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiRating.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e65f9ea22053f8820c3829cc0241c2ecd210368c6658496e1e0a350084f214b0"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSearch.OnSearch \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9b848d3217b447235d654d06ce69e63370fb87a7927ecee845b4feaba08212d4"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSelect.Filter \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"09a90951df445a6b1d699edd1b2423e1145d3df6ba1547d3c1951c22d86b4674"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSelect.OnSearch \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e2f5e7bdcc077e5e7e86193b32522b5dfe0f053051800443b3937d64a75d13a8"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSelect.OptionDisabled \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"faf5569b7741e8c7cdbe5d233ba3c1985220ba11c53b9a58d5ece9181e968447"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSelect.OptionGroup \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"3997e8232b99a5cc9d92f58e1c13d25d689b0f72b866f6814487ee4f57960d0c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSelect.OptionTemplate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9f4468d64ed2f5b9ef711cfd18e890101ca8ce13eaa76ae0c1007572cd128ef6"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSidebar.OnToggle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"076dc9c969e262bbde26ed9ddedce6294231b5bfb821222dabfde6834816d6ea"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSidebar.OnCollapse \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"11008542e9e5256db36c8f54ca1a3b74deeb1e1f20dbe357f99c5d89cbbd6fde"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type RouteUrl (Rask.Core \u2192 Rask.Ui): RouteUrl (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiStat.Href \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e11c8d276e5df249e199d4024d8498e8e1daf04370e39a5939db8ef4b09b7b68"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiSwap.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"0c9c8799ec08525f11cab514968724784b9792bb624a0cdca640fa6cba91e3a1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiTabGroup.OnSelect \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d2a3be560290c34a161c03f3734885f26f55e6aeb9297c702a933c77b50329a3"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiTextarea.OnInput \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"66b14866da3458a56b194301c8709fe9321e2f00d7c89548863b70af8a90f119"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiToast.OnDismiss \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d52fc9efeef4d0fd94c97f346fc2f8400d9b2c41af6a55787bdd67449eba2ad6"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiToggle.OnChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"50474bc9e876d16d3ff3c2b88b013b86bc22b33b419d2f471584cc5440131903"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Validator (Rask.Core \u2192 Rask.Ui): Validator (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiToggle.Validate \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"453d08a8c409f45ee8d2c18e5732bad7aa6853a00d7f2976d28be19e82ae4c8b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiToggle.AfterBind \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7950c78b7cb67cad191f645dbe372fc4f9053f30bc6044072fa6a2c417970d3a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiTree.OnExpandedChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cb31809a2a170e8dfe7f500f8c6284d4eb070ee6cc427427c7fa97ee8bde173d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiTree.OnSelectionChange \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6d4a4a257a05855df2addbb24ffb38e54cf4ca38c09520b6a08964407c85332a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Fn (Rask.Core \u2192 Rask.Ui): Fn (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiTree.NodeText \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d923db64f4eb7503c8e380a9cb2d14360c8e95fc75dc6124141baf1b26825cfe"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type Callback (Rask.Core \u2192 Rask.Ui): Callback (context Rask.Core) is exposed in Rask.Ui\u0027s public surface via UiTree.OnHover \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"76eb53e71356f10ced8dc80cb2e3cb36cf95ace7f99e6fb6b5d3bcd2f8ede528"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type FieldIdentifier (Rask.Core \u2192 Rask.Validation.FluentValidation): FieldIdentifier (context Rask.Core) is exposed in Rask.Validation.FluentValidation\u0027s public surface via FluentValidationFieldValidator.ValidateFieldAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"dcbf3719f0b90a27efde4a4c1c8335bf67271cc9d274acb124d8c15b694dfda6"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type WebAppManifest (Rask.Core \u2192 Rask.Wasm): WebAppManifest (context Rask.Core) is exposed in Rask.Wasm\u0027s public surface via WasmHostBuilder.UsePwa \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"072aa46fb4189f4611f6c34ec0ddaf45cb9fd2a3b025b7f8e8d225e0b4678069"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type WebAppManifest (Rask.Core \u2192 Rask.Wasm): WebAppManifest (context Rask.Core) is exposed in Rask.Wasm\u0027s public surface via WasmHostBuilder.UseManifest \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"1afe8eab879e0290f9ec7d784ae91053f3f17f961ec7cc28b5c1d47e6b8a5bfc"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type MediaStreamId (Rask.Core \u2192 Rask.Wasm): MediaStreamId (context Rask.Core) is exposed in Rask.Wasm\u0027s public surface via IMediaStreamHandle.Id \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f84efc8c8687c9f5f01910bb90c07ac00a1a89b8c04be4d0a80649214c43ac3c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ShareData (Rask.Core \u2192 Rask.Wasm): ShareData (context Rask.Core) is exposed in Rask.Wasm\u0027s public surface via IShare.ShareAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"229ea26fb7cc991bf240e21820ae5b641e36cae8d637b8fba328b6b34cde3c28"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ShareData (Rask.Core \u2192 Rask.Wasm): ShareData (context Rask.Core) is exposed in Rask.Wasm\u0027s public surface via IShare.CanShareAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"eaa0d2c5df8952a2d16596cfa82433d41939819ac6b1e78559b2dc18cf529c9c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ShareData (Rask.Core \u2192 Rask.Wasm): ShareData (context Rask.Core) is exposed in Rask.Wasm\u0027s public surface via Share.ShareAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6c15ae457fc5173bfbe1896ccc33470db1ad7dc34109df5d25d2a1bdee451356"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ShareData (Rask.Core \u2192 Rask.Wasm): ShareData (context Rask.Core) is exposed in Rask.Wasm\u0027s public surface via Share.CanShareAsync \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6c2771eaf9c34e3c618db1b90c3951101e0e2a929a52f3c2eac48559034f9130"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type WebAppManifest (Rask.Core \u2192 Rask): WebAppManifest (context Rask.Core) is exposed in Rask\u0027s public surface via RaskAppOptions.Pwa \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e4b6a622a96eb90a9312887018e88fa6e665391a1bfb474b9a63133b144d582f"}},{"ruleId":"D24","level":"note","message":{"text":"redundant comment: \u0022C#-minted id\u0022 \u2014 "},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Wasm.Tests/Browser/SerialTests.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecf210fc598befdea16fc02d8eebb71d0b0aa7aa2174a25cb4b296a4296e3724"}},{"ruleId":"D26","level":"note","message":{"text":"Projects may be oversized for their cohesion: 3 of 120 project(s) overshoot their size bounds, lowering Project Cohesion to 9.5/10. The most over is \u0060Rask.Core(net10.0)\u0060 (35183 LoC, 529 public types across 15 namespaces). Review these for cohesion \u2014 split a project that spans unrelated responsibilities."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d5a94650dc74886a0f1f08eb9fb6775f1fc395279ef7e901c970c9d26f767a72"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"64843252ac338ca2b118993b58c0ce255e86cc97df9875b000ad4f59849be6ac"},"properties":{"commitSha":"30c0aaa0dc58eda4a78510b32228c6c91d74b137"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4b3e088b88e4b9c3ea3d8c931f41c9ba4bfcad562d9110be7efe54d8f86c17c7"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d410b1e6137ccc5740c9ac6dd290a7924a74628e06c51707aca55920b82c0ae7"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c1e553f756786c80a3b2f7b8c3b604f6b1cae4258c2cf9b780f013fd2364ff88"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ce65f14ebf1181d56ad0ba3731471ee4218cbca07c73bc8e2d84a3a7fb82a74a"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d445e640b5570410aad3b9b3b41d0cc19f15483a15e6ab8a530b32cc3b4ffdda"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9e468956aa362c4dbae3727794322556f060a1c73447e4df0ae8788d3c7d5941"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2891c32426d282400a0030dc93f14c580d5fa186cdc16bb158e767bf3bc079a4"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bfee83b583e465345a1f2c4e906b9b4e9517c3e4fadf194d31107551abdf296b"},"properties":{"commitSha":"abdd7e78c79fe58d6194d5bc65a4a8c217444143"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e689b007122367b8be96a83fd96fd758b4eb842813ec41efb482cc38e6eaf047"},"properties":{"commitSha":"40bbd534412ad1da5f42308dbd9a753d4876e1d0"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bad8924ffc34107587ca132ba6a65d592c9c811b01dafc5f7046858f22d7b67e"},"properties":{"commitSha":"40bbd534412ad1da5f42308dbd9a753d4876e1d0"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"da2a8f57b275a0338c10e68a1a87fe71eedcdf8f39e4446b90d301ee24836bf2"},"properties":{"commitSha":"b102194b184023dcec2718f1ab2637ea1082a8e3"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6e7c1a978fd40318945c98aefdd0f09a9041a2ad181137ac253ddcdf09027ebf"},"properties":{"commitSha":"b102194b184023dcec2718f1ab2637ea1082a8e3"}},{"ruleId":"D28","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3cdfd7beb31b791ae18dcb425e21eb157c842e7bbcd522cc330573c1a6538db1"}},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1eaa3eba8431e8cea32ff0b5ca6da595eb7b2eecad067a9ea95af9531f36d779"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"374934f889302079d75d33239d90edac2e2f2e4786977e28979dc58a4a320838"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a619a6fac3c87513eee8c2f95072932e19dd25628fc90a2382445d68d58a0b8a"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3e2b3183f3c5ad97f177713bca5c6c922c0c4de61a0673d5a699bd50b5586c2c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ad7425c5dd1571e5c3b7118afa40ce8777ba2b9feda3c0ecd8503eda655c1733"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"96c732362b282e043066ae5c2dd48d77d6c885a7cf48c491f72bfc1a024e5609"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d5b8f11381d61a58459ffc7c595fd52d09c03c711894a63a9578043d2338412b"},"taxa":[{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0a2652006d5eb3a33a5d2cb1834128f3f7076b4dcbc6aaf024d01f6a7b7bcef7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f8af5d7c32e862fd11c825a182df1bc7670faf68f2e12fc8cfe6ef49883f81ad"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6e4f326ebf834c2767b4b96324aa8a95f35a19b60f75f81438eead97459bc696"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"341fef30e40c699fa8a97a3d601f89fa38aa7f3e554faea4a64aa429c32105e0"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c7c7f733fea7a32e7845b51c5b6e5f20180b17c7aa6cb0b97593581554a014d8"},"taxa":[{"id":"CWE-214","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-532","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bc5afd897179d06095614b2fce28b0f209d9c3b78a60c2b88d575107a6cf0cdc"},"taxa":[{"id":"CWE-214","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-532","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"97b0c73d07579153fee674fb0fb660d2fa8a200158467809cab45b0fe07752e6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"46ed5088e372a1645841089d14aca0a25845741310820ce62e7cb1a6cd16763b"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"29a123e5ded039aafc5f9608aaec5c5e039833e07d8997aa993c9ad344fa17f1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e4cb465e1f0d2eae4c574d9bbda594dca37b461c20ca4391a9a1ab1fb76b76e5"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"34f998d59eaff18b05f62f3ffd53eb1d86ddd758e021a3b06f3dd141181d69a1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"693249723480b7d3690fbc9002e4acaa2fd5c4f5277d52948268b51530c89d1e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7adc332f2d68b4a8e35c8868ce3df7038dc1a68ece15e2a5c16dee165f7a002c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b045f06583c9b465f808666ab807bb301b75e163408a0670ffe050a381f461f6"},"taxa":[{"id":"CWE-214","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-532","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5ecff609e0b8130943e85eee7e52bd1b64c207b9151c9670170facc8d62137f3"},"taxa":[{"id":"CWE-88","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d92b199eafa839d11bfa7a46bbf361a28ddeba20d8946c59a90b64164b4b66b7"},"taxa":[{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b7909b7b4f76840c80b63272a9a9d9f2993fca75c998672e8cf8568275038053"},"taxa":[{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"766db35201c7fe139595e689abe8c1739273db6274ba4b66e176061391dbfb89"},"taxa":[{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b21f0a31f8d678c081b10a0f0f190553126813fae55c3082320346ba3609ec0f"},"taxa":[{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cfa543fd1e2fdc26b268f68d781c09cad8f926214d2ca543e3ccb68d1b80848a"},"taxa":[{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cc320b4a775e587de2fbf7eae2d97e0dde98ba95f7fb6da107ce2ed1a1d3a2cf"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-552","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"63778fa624412affc09bbae17ed4e235deee47c1e8fbbd49594e08c2f223c987"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-552","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8bf209f1da9b919b0c2b09edfb007c530b1d43c748a77699716926b7061576a0"},"taxa":[{"id":"CWE-345","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"27d0c8d8001c702c89e8941c823990ebfa6961e55fe279c05f1c8f395cdd5c0a"},"taxa":[{"id":"CWE-345","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1532e8d6bb7c107cecb150244c97d3fd33c1ebae78925c8405d775391b0aacb4"},"taxa":[{"id":"CWE-345","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"95e9e6bada10b4b7e6f111737e38a0f6bfecdc8e34e4b760ec2969d6bc6009ee"},"taxa":[{"id":"CWE-345","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cd0caf94d46e794c5ce6d64568d5cd30db1a5bd2421354a44be6c575105ccd36"},"taxa":[{"id":"CWE-22","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0bfab47f9a162b9f9fa32e1ec41f2e84469165df6706a5632b02bed423b3ddac"}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"08208a2288f56bbae763a1de121083a60234981aea8fb76334b8ab585e26bd0a"}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1de56bac5de608fa0fb7d473ae3c9931caa1013f1a2336b450daea61f1467b7c"}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a11f99b43c4e7d36159d8fda79e0e36afbc040d965ef91ef636c9e0bce31df52"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1b612475652936b399d58d1cbc524a6d9557c8d0310a4bd0cf0b7f94ee0bf99f"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d30f31b1a1d724ceeeca67c8b152a80510ec89ce985d06950858cf2c5da3fdd9"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bd5b4034a36ec38d946544292c7e2bf7820feeed8b91df74246c938c55b86943"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f419cba2a12906b91aaac0db6a72b243f254047d84ef0d98d11edd4821d38c47"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6470dc9dff83f33f259323bcb899452a38aee52c280aa281f0325408d6450d0c"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"34ca0973ccc8c994bc0e74953c703f81eee3c175583a4039b14b8673f5982895"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"530eb12ad1d0ff9e51fc5af95c687cd47fecb597ff65fa89e41e8e219c5aaa71"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"60c378f1c498b02e46dbaeb4a36515a5cbf59c26e9abe7f0e9dbeccdfa67cccb"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9a461b027b547c0f1e11a69969892277f6071c3ab8900c7111aacf3d8ff61969"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"01e8b53ff7e49ddf36631db72a8cdcb7ad5e9ddb58d267ff9a4da1a20b23bb96"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"13f06e8d16cbafb2949362eb0bc4e85ad4fbb85f24f07a7abed58f315e1fa798"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"26f26075d6ec9aab28af5551938998e7540dbe52b576ce4aaaca6c25a8afe427"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6e733c872348ab2690d42e967f098e23aa36f816ba0f63568fb163d2d14ab3d4"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5492d07bf5b341ed13014964c7cd2cadbd308343c81c703e2bd5cb1d6808dead"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"82901ff6b641111e7db7ffab92a3cf7a346c10d91f71c9edc292e989ff1ad91d"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8c78a98d951a8f172e6d8ad29f9a74a83ef2f6caf66328d471d27f2c8433c2a7"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e59a8cb369ed6c9864b44d9f2d4a35fb8da46a994bcedc7f43040b4ce37439ae"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e281b1a8744e88b1e45feb9d4e07c689034b8f9b283e51fad47996666edf5002"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c911b57d91e56b76c271742dd56d0b2a0714fc9c62697a4e753129db29fee0ce"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d681abe29bd805944ad9fab1b75cebfc0a3027b9af9e8a1a8eae1c26c66096b1"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cabbeb2b3aada38502800cb58141f6b4786a971026ba3f701982e811250f99fe"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8f1d45723e75b5bf3c4afafcb9afbb969a8f237c102d592bb944334dcd6128f9"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"520f05f19d438800f655cea573aaf294218d983e4eb1ce416c8a412a34613f59"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"05420ba253c1d0c201adec3d0eb8f26c8fcd4bcd738a3380bdc5d6cf077dc22c"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6d49c79f95b9c623dc8966ec15ef9612de5ff939a41455eb45c24e05098751ad"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"216f8934fd733d0e03c8fc65843af35a48f74a9cb38a4e2da4c64a98461adb60"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"57163ed255f2c935e09c781c62307c1dd3e618e9de1c6fffbc9a1a5051fc54ff"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"79a3fd1bf8b7f82bb7fb5ae3e377882629f14b363a2d4f2f2e3c7f052b065fcf"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b5d69a174919d440cdd4863c2ecec9bedaa922c3a8445246a2e57e06f45cfb43"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d1b9f4deb9fc9660b9ad9f3251950eac713554a3fd9b61b73de6f9fb2a82d222"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2a5d85f14789a97a5de62f50de9f4c153ae2cffe90f1350b78ec8d8996365f6b"}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f8147ff8196b2c1cb5dc89731188c62269fbfb28f6fe35f18fd43d53c2283c72"},"taxa":[{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a805c9a2e4d1ff89ee863fc7721a1b2e94c73970ea4959b08bee96ee81ccffd9"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a632a54ecbb4404630ffc2622583ecafeeeb09acac06b4f977c1c2617f19c258"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b99e9fe7a4086e59d13dedcdee1c2e457b8a41b375ec2047400d97f32a031ce6"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1c4f388399c6fcce47fc44775f31fa35d3d0251a08153af28abd6b3da664bf39"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"33652ae192219bad069a72a7c425980fae5eac63d12493147bd2080964fe3168"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bcbe9947bdcb0c08f4679020a0712b07093941fe35c85d0729b051baaf37987f"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3fa45ec34776306bc67301f0bbaa14ea50c63858f18e27abf186ea548083a6e6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4f83a5e4626cfb6a0396fab45166247a4fb79d0804f20649f89b11a96d9be913"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"81a988c241d4aff4e24414c661477681c623cdff6e198fd011360b938d5c3ce3"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fe26746009cee38ce7e4d5bd1a6c37b0fa82707fba493961a9b14d5eb803a907"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"12bca9af89491ffbb6e67f7076c91669ebbb4e4c01aeac3c30b116d47b1a108e"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cbe4136de87c462adb5b39af11ce4b2fd7b5c4879f5b2cb2717aa8517f19e096"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7c452ad2812b30cc5186f28c52b4a5d315f2bd7fa9ed0ef09ced9a3715341ae9"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f5e040ba7186c0132c7b0355ed771f9cd7d3ea10bc2930487bf045eb5f9e0829"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bda76d0db4d3c1c96684d1bacb3e460deac6150d92457283e948f60cd8a0655b"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f1187d4ee2e33dcaa8f7d51b1bad8275494237396d50a45f0b56ca0b663b1fcc"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"065db5d21915a8f0721767c4c99558985e733e3e61d2705780327d35d5569595"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d44fece9906f983c7845fe61f37a2a5592812a1e3dbcd1f02d196cda135a9e40"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b4b5af4e5dbf657fd7ece5b59aa6c9a10d45b8605475be751f7fb97e6df4b6a8"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f18361d01ea35400fcf506e0027011f74375b0fd7a89b95d511b8b09aec42b06"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ba39e88d3b2be071596eaf5b534de873f497e939461b0e6f87d328a834a0568c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8830d215b3b3cbab5662e4ec6bbbedacb4acfc1ccf1e7ab29e6b8f81206b2aff"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5d4d4e333a343c7e26eb55bd619f87b87272e759ab4a1d81117eddd46308c196"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b53c1dc1f4d4a5f4ac4ffd9e49c626530716afc5445298ec971db38dffcabc47"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a8367c430e130a6ef51dc685b697c0fdb5829211e9be07c0434dc9e30ce2b6b7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"64a41fff8d40c84b03c08db78e658e04de267809c9e5558660ec035fbcb9bbc1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"43fcfd863a578689488ad7f299a2da466b4b6b97de0675d0d8db9e9c66b338c8"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"155a58a2de46499649e6f330a7a95bede0bfd4789af8be33b432225723f8441d"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"09ce46afc1bf87b509c8ba61120babf86b15493e63e13f31490e0d7b5b45ea0d"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2cb0395159352be569220017beb8efb8cd60c1f67e35c4cf037e2c0f72276452"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"82f3e38c0af702f12449abd5f2bf0dd72b14c86262740f4c0be081954e4fe93b"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f929fd07250a32cf3d5c46b662b8297fd663e4c5320270d7e14b5ab340bf7e31"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"77a140b99a3b384f21304852c1197faf9db26173a0f9b819a730fd616fbce119"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bf16a754e7039d457714fce769bc5ba77844a5ff835dc2a97a4422da6ebf1d62"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"38b4c76433b7bddf1739a5b7a8813f0fbbabae022352adc666ae9fabb84d4bc9"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cbaa0662681e4e3cfa2818d75fe10130a0af7f934aa7bcec0cdb14253a6441c6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ff8f081cfd72251159bf8782c80390a378fc1d920f3bea2258c78e1f18be4b6d"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"46ce7036833934466c4cbaa967efdca804458d392afb9b9bdf566214f7b66af4"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"aa8c9fbd18058b9ea4fea0617dcdb200e90ec1dc030fe6dfe789cc65c6981abe"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5217513fc0190f25284c1d720fb40ec2ad969dd96afb20355eaa99c33a7e5376"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"24d4d61e754a86c78af74b4071d96bade118b2eb6fb46fbf35541f2e2e4c2c92"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9a18df70f3a1225a5df02df8fa5f4514e37030470f85ae6ee8070f30213dc18c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d7460ba21870c31488f876ef2bd14b913b624f2413be86fd96958f246b0db9e6"}},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2e8ff942a38a77d40ed608c9b13a2536087a8a5e8dd0276efbe490c57c2f3fc2"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"be2945b331b175436ee7c545f16ff9430a38d172926492d8db222d6a3080e9b1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"eb06590435000d1858e72fb02db00e6f2bdf91fdbeddd3ce7bdaf745b3b92e25"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b520a0de88dd3415cd1818df779d39ec7570fc47ef5cc3c2d4ca37c21e5149f1"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f768d4f3430687d1a6d6de362ce823defd71f7653431481d4ba34b2c2bbef63f"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"24644d751a1962e5dbe432a8a2a10aea9c4f02153833b6d1baf4cde456340423"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"65b0f3c9d2ecb4d8f25dff57792fcf1f4f5f1cecac12fcddfd9ef8b01e7be5c2"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"de842324650be1f222b15321a2fe1d3c64f092c6b6a1568de109d63f46e52d23"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f16386c2ac624851c748670caf6765b38026f9b214202ea52b62682f96580beb"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"05eefa4ed9a139462f60b658c79cafdbfd8bc314a9084e10979b8c4ce8ef6ec9"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4f352db5f9ade388c23939b8ec91ee3c26a67936268f68cd9e258d799e85553f"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"45a4180cb830c69ebacf93c4edfd955cb4e2a8d6273a5589d7521a4117a50c53"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d97af5dec8cbe2de10ee2750c7da1af719452bc2f8110a83321a662669e96b1a"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7566cb115cf5041e09ef5a1eb15e7c9813a6419d5f90a3245b590b7ef36ff9f1"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"58597eedc95341a4183a81d122b8e5201b7f67d73c8a0c3152baa780d116c167"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bc0f10454534d21aec7718f4e881fa70cbdd0c10c2f005797a36f4e7c24d0da4"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7ca6ac0d655fc7efc24af4711d9e505da815c26d7e4020f28ed61a504495bf51"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0f038b620f1269b185a21828e12df081b5ab7e497b9393967eaa723c71704ba3"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cc7f11b97be03d268c1bcecacfed62e225c5cb58ce72ec8a957df4ee606a1a9f"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a0726137f2fb433c065941503a8cff39c6b48374560a2a9bc50a0980522cf2e4"}},{"ruleId":"D31","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"39f12229874e50c06bcfaa20a04538cdae4a895514de6abc491818e44582b377"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: RaskBrowserJsonContext.cs \u2194 rask-api.ts: \u0060src/Rask.Core/Browser/RaskBrowserJsonContext.cs\u0060 and \u0060src/Rask.Core/Resources/rask-api.ts\u0060 change together 100% of the time (16 of the 16 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) and are written in DIFFERENT LANGUAGES, so no import can join them and they cannot be co-located into one unit \u2014 they compile and ship as separate artifacts. What binds them is a CONTRACT across that boundary \u2014 an event or message name, a route, a serialised shape \u2014 that each side currently spells out on its own, which is exactly why a change to one drags the other. Declare that contract once where both sides read it (a shared schema, a generated constants file, an interface-definition file) so a change on one side fails the other\u0027s build instead of drifting silently; where the surface is too small to be worth that, name the counterpart in a comment on both sides so the next reader finds it. There is nothing here to merge. You can check this without leaving the row: of the 16 shared commits counted here, the most recent 3 are \u006055d0aa8e\u0060 feat(core): add IWebAnimations over Element.animate() (#740) (at that commit the file was still \u0060src/Rask.Core/Resources/rask-api.js\u0060); \u006001f55ff3\u0060 feat(core): add IWebRtc \u2014 peer connections and data channels on every\u2026 (at that commit the file was still \u0060src/Rask.Core/Resources/rask-api.js\u0060); \u0060b491b38a\u0060 feat(core): add ISpeechRecognition typed wrapper for the SpeechRecogn\u2026 (at that commit the file was still \u0060src/Rask.Core/Resources/rask-api.js\u0060) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/RaskBrowserJsonContext.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4df7d794e950babd3de65ef88b1703e5e74f724a7687c1004479579071b756e2"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: ProjectGenerator.Server.cs \u2194 TemplateCatalog.cs: \u0060src/Rask.Cli/Scaffolding/ProjectGenerator.Server.cs\u0060 and \u0060src/Rask.Cli/Templates/TemplateCatalog.cs\u0060 change together 67% of the time (8 of the 12 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets). They sit in different directories, but in this ecosystem the namespace is declared in the FILE, not by the folder \u2014 so the two may well share one namespace and reference each other with no import for this pass to see. Read the pair before acting: if one derives from or overrides the other, the dependency is explicit in the type declaration and the co-change is definitional; if one registers itself into the other through a hook or an initialiser, the missing dependency is DELIBERATE and the thing to add is a comment saying so; if they simply belong together, co-locate them; if none of these holds, the coupling is hidden and worth breaking. You can check this without leaving the row: of the 8 shared commits counted here, the most recent 3 are \u00602f3fc33c\u0060 feat(cli): rask new scaffolds file storage, and --no-storage leaves i\u2026; \u006042fec38c\u0060 feat(cli)!: languages are configured in Program.cs, not on the comman\u2026; \u0060c0d3f51d\u0060 feat(cli): scaffold real localization on the browser-WASM templates (\u2026 \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Scaffolding/ProjectGenerator.Server.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29f71ba769e28dc6e6a9ec08b6790457a96beecba137453fa1ffea5a7034e679"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: rask-wasm-api.ts \u2194 WasmHostBuilder.cs: \u0060src/Rask.Wasm/Resources/rask-wasm-api.ts\u0060 and \u0060src/Rask.Wasm/WasmHostBuilder.cs\u0060 change together 60% of the time (9 of the 15 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) and are written in DIFFERENT LANGUAGES, so no import can join them and they cannot be co-located into one unit \u2014 they compile and ship as separate artifacts. What binds them is a CONTRACT across that boundary \u2014 an event or message name, a route, a serialised shape \u2014 that each side currently spells out on its own, which is exactly why a change to one drags the other. Declare that contract once where both sides read it (a shared schema, a generated constants file, an interface-definition file) so a change on one side fails the other\u0027s build instead of drifting silently; where the surface is too small to be worth that, name the counterpart in a comment on both sides so the next reader finds it. There is nothing here to merge. You can check this without leaving the row: of the 9 shared commits counted here, the most recent 3 are \u006037b0cb40\u0060 feat(interop): Web Bluetooth \u2014 IBluetooth (WASM-only, Rask.Wasm.Brows\u2026 (at that commit the file was still \u0060src/Rask.Wasm/Resources/rask-wasm-api.js\u0060); \u00609085d427\u0060 feat(interop): WebHID \u2014 IHid (WASM-only, Rask.Wasm.Browser) (#195) (at that commit the file was still \u0060src/Rask.Wasm/Resources/rask-wasm-api.js\u0060); \u0060db530a53\u0060 feat(interop): WebUSB \u2014 IUsb (WASM-only, Rask.Wasm.Browser) (#193) (at that commit the file was still \u0060src/Rask.Wasm/Resources/rask-wasm-api.js\u0060) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"41169ce49f45c8e7d05e208285dc0b985290bc933f1034088276ad8dbfef2527"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1b213f6eedd4b140d0bc37bdf1496f72811a643f34064f12518b32e9e83bcfc7"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0e17f71490e4d120a48b2b2881ab866c93b272bef2febb673a3e8e42b2c288ab"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"eb00976a698a5d68999b7ee6d27206fd374e916853e7ff1ead5eed42386f043f"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"90f83b4fa27db32740afe9540c905f3c0499caed87f61049a8a903ecc95b41c3"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c5928b81075799790cb18fed2980a6b6e8aa5072772041c9951633efe8eb3542"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d657599f6f99da1927d3377533dfc0888b34c4d84aa7d5579841fd72d0e39bce"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"assets/og-card.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bf71a0812cbec851d35b73adaec4aa054c24a0fc391e6fe4b81aa5efd1d4ba7"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/wwwroot/index.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"0017bbe97d7b000832db623c6f9855ae32f09b1446aa4703260cb0bd64f426ea"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/lit/client/index.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3dea2647282fb9f1641fc81643ea6b76075d9ebb10cd73354dc27cf068710cd"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/server/wwwroot/offline.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dd905ddc063d67c409096d50a483280ae792b081713065066704694244e8183"}},{"ruleId":"AC3","level":"error","message":{"text":"Document without a \u003Ctitle\u003E: A page with no \u003Ctitle\u003E gives no name in the tab, history or screen-reader page list. Add a descriptive \u003Ctitle\u003E in \u003Chead\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/sveltekit/client/src/app.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"2be6b5d5aa7b76789f925fc6178489254f235b8b89d075b2cdaa0c363931d1f4"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/wasm-hosted/Client/wwwroot/index.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"068523fcf18afdf125ef099b8a892b8f26e3eb3fcadc30fe745990d8e8c97f7a"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/wasm/wwwroot/index.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"a76f21e8a7cbc067d8375ed244da82486a74d840ed45f86879b24b58b24a783b"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Browser/index.html"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"abf5f76b61e4d5e5093863a8fb77b168c806dbcb44438d593b2aa6b2c1905d71"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: This stylesheet animates but never checks prefers-reduced-motion, so motion-sensitive users can\u0027t opt out. Wrap motion in @media (prefers-reduced-motion: no-preference)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/wwwroot/index.html"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"c483c0c62e7c06e0f74c1ae4c9f807f2e1718819a2ac4adbaa5752a698d811a8"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: This stylesheet animates but never checks prefers-reduced-motion, so motion-sensitive users can\u0027t opt out. Wrap motion in @media (prefers-reduced-motion: no-preference)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/wasm-hosted/Client/wwwroot/index.html"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"e456c1ae545fa14ea5d9b5f201ba80a36ec9931c3b8b5475235213091dfa2b35"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: This stylesheet animates but never checks prefers-reduced-motion, so motion-sensitive users can\u0027t opt out. Wrap motion in @media (prefers-reduced-motion: no-preference)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/wasm/wwwroot/index.html"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"7740dddbde2289f42fc993e13c15e10f4882072cb427848e13a26419dc296568"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: This stylesheet animates but never checks prefers-reduced-motion, so motion-sensitive users can\u0027t opt out. Wrap motion in @media (prefers-reduced-motion: no-preference)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Browser/index.html"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6e97049e1f6d35e90e04b6e464ca9fac0a3ffebd9b1fc16374eef8927d75500"}},{"ruleId":"AC7","level":"note","message":{"text":"Accessibility enforcement below the top rung: An a11y linter is configured (Documented) but there\u0027s no automated a11y test or CI gate. Add vitest-axe to verify at runtime, then gate it in CI. What was searched, so you can tell an absence from a miss: the 81 markup file(s) this pass actually assessed, the linter configuration checked in beside them, and this repository\u0027s test and CI files \u2014 matched by name against the accessibility checkers this dimension carries. An audit run outside the repository, a hosted scanner, or a check whose name is not one of those, is not seen here."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d46019b86eff5ddad9db289e6802ac158899e980df54c34f67722442787ead62"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: HttpUserProvider: \u0060HttpUserProvider\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (IsLoading, _loaded, _current; e.g. \u0060IsLoading\u0060 at line 59)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Auth.Client/HttpUserProvider.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbf41e3e319556dc5708fd45e705341bc11336f7c069af57829627d3f0a1056a"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: RouteState: \u0060RouteState\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (_path, _query; e.g. \u0060_path\u0060 at line 35)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Routing/RouteState.cs"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"db1279743ed9ea36d04da6dd10a4709f754915bb0bef3d6ab516b50cc121bf06"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: Navigator: \u0060Navigator\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (_replace, _dirty, _inInitialRender, _inHandler; e.g. \u0060_replace\u0060 at line 76)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Routing/Navigator.cs"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"997d617e87d64590b9617b57ab3ea56977f006a63aa537a4f2119235d29139d3"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: BrowserSqliteOptions: \u0060BrowserSqliteOptions\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (DatabasePath; e.g. \u0060DatabasePath\u0060 at line 77)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite.Browser/BrowserSqliteOptions.cs"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4e3f8b6cdcf6e2041d79cb147a0842345f863ba9de0eb83189df4e5621de840"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: BrowserSqliteHost: \u0060BrowserSqliteHost\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (IsOwner, _takeoverWatch, _ownerHold; e.g. \u0060IsOwner\u0060 at line 61)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite.Browser/BrowserSqliteHost.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc445280567eb8130c71b9c65dc129241575724a3032e887b3ce9acfbe0e7f25"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: PersistentState: \u0060PersistentState\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (_bytes, _entries, Version, Overflowed; e.g. \u0060_bytes\u0060 at line 119)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/PersistentState.cs"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"af11ac5c7692ceff8ba9283afb7612baf6da7f54ac4ab7fc3ed8b7a7139023f0"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: WasmDownloadSink: \u0060WasmDownloadSink\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (_order, _pending; e.g. \u0060_order\u0060 at line 32)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Files/WasmDownloadSink.cs"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"d865034e37d7518de5c466af88c7f545d2f7b9da04cf889a4db9eb43d7d1baa5"}},{"ruleId":"AX2","level":"warning","message":{"text":"Stateful singleton: WasmJSRuntime: \u0060WasmJSRuntime\u0060 is a singleton (one shared instance) but mutates instance state outside any lock (_host; e.g. \u0060_host\u0060 at line 65)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/JSInterop/WasmJSRuntime.cs"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9dff0e9179e8eec87b39e22a99e5993d0d0c6314b77d11a517b8a9379d37a93"}},{"ruleId":"AX6","level":"note","message":{"text":"Fat interface: IQueryClient (17 members): \u0060IQueryClient\u0060 declares 17 members under just 8 distinct name(s): \u0060Query\u0060, \u0060Query\u0060, \u0060FetchAsync\u0060, \u0060PrefetchAsync\u0060, \u0060SendAsync\u0060, \u0060SendAsync\u0060, \u0060Command\u0060, \u0060Command\u0060, \u0060Command\u0060, \u0060Invalidate\u0060, \u0060Invalidate\u0060, \u0060Invalidate\u0060, \u0060Invalidate\u0060, \u0060Invalidate\u0060, \u0060InvalidateAll\u0060, \u0060SetData\u0060, \u0060SetData\u0060. Counted as the author wrote them \u2014 a property is ONE member and its get/set accessors are not counted separately, and an event counts once. That is an OVERLOAD SET, not 17 separate responsibilities: a caller binds to 8 operation(s) and uses the overload it selected, so the Interface-Segregation harm does NOT apply on the caller\u0027s side and splitting this into role-interfaces would scatter one operation without relieving anything. The burden that does remain is the IMPLEMENTER\u0027s \u2014 all 17 signatures must be written and kept in step. Reduce it by collapsing overloads (optional or default parameters, or an options object) rather than by segregating the interface."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Query/IQueryClient.cs"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dd7a13ab94fab9034031fac287da9470b6f39bf90957c9c9337c0328c1d3e0d"}},{"ruleId":"C3","level":"note","message":{"text":"Partial audit-trail evidence: An audit mechanism is present, but the trail is not yet complete \u2014 missing: an immutable audit-log / audit-trail type to write to, [Audited] per-entity coverage."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"274a04e524f3228d241c99316455563739cb06cfd10a01e446d00b8a14956083"}},{"ruleId":"C4","level":"note","message":{"text":"Partial data-retention evidence: A retention mechanism is present, but the data-lifecycle is not yet complete \u2014 missing: a scheduled purge / cleanup job (PurgeOlderThan / CleanupJob)."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e6c843eccaff7ffcfe5241125b74768c2364055ab6678b12b10d47f44086afa4"}},{"ruleId":"DM4","level":"warning","message":{"text":"Anemic entity: QueuedMail: \u0060QueuedMail\u0060 is an aggregate/entity with 15 data propert(ies) but no state-changing behaviour (only data and queries) \u2014 the business logic lives in a service."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Mail/QueuedMail.cs"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"e818816894c8649cd353f304c502903c4d4b3a3230ad4e74f5958643b9be28f5"}},{"ruleId":"DM9","level":"note","message":{"text":"Rule about [HighlightMarker, SnippetMarker] decided in 2 places: Rask.SQLite.FullTextSearchQueryInterceptor\u0027s [HighlightMarker, SnippetMarker] are judged in Rask.SQLite.FullTextSearchQueryInterceptor.Rewriter, Rask.SQLite.FullTextSearchQueryInterceptor.SearchFinder \u2014 the same decision, restated. Every copy is a chance to drift, and copies drift silently because each one looks correct on its own. Move the judgement onto the type that owns the members and let the call sites ask it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d3d45096c011a4b7717d47cb866ce799f14955eeef5a14d4cada0d0f40c85328"}},{"ruleId":"ED5","level":"warning","message":{"text":"Non-idempotent mutation: Features.IncrementCounterHandler.HandleAsync: \u0060Features.IncrementCounterHandler.HandleAsync\u0060 mutates persistent state (an event publish) with no idempotency guard, and the model confirms a re-run would double-apply it. A retry or at-least-once redelivery means it can run twice \u2014 add an exists/dedup check, an upsert, an idempotency-key/inbox, or a versioned write."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Cqrs/CounterSlice.cs"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bee2b31847cd26a5cd4403a273e479405d2c941559d87588b05836558f36a04"}},{"ruleId":"GD1","level":"note","message":{"text":"Placeholder literal left in code: A placeholder string (\u0022[Rask.Prerender] no sitemap \u2014 set \u003CRaskS\u2026\u0022) is still in shipped code \u2014 typical of generated boilerplate that was never filled in."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/WasmPrerender.cs"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"3aaa871f22de6977cbf3bee464b2d989c4b80205d1b94bde8bf63ad6a610580e"}},{"ruleId":"IC1","level":"warning","message":{"text":"Empty method body \u2014 does nothing with its inputs: \u0060ApplyRender\u0060 takes parameters but its body is empty \u2014 it accepts inputs and does nothing. Either implement it or remove it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/JSInterop.cs"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"74cea18f3859e3c09509d85002a24caaa7271461bfd2312e3eef040e9d9e4bff"}},{"ruleId":"IC1","level":"warning","message":{"text":"Empty method body \u2014 does nothing with its inputs: \u0060PushHistory\u0060 takes parameters but its body is empty \u2014 it accepts inputs and does nothing. Either implement it or remove it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/JSInterop.cs"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"e27b35dff41100352c96fa1ee704567577ab8260cf8a0874f51ce5454c29ee92"}},{"ruleId":"IC1","level":"warning","message":{"text":"Hollow method \u2014 returns a constant without doing the work: \u0060ReadFileChunkAsync\u0060 looks like it should compute a result but its body just returns a constant \u2014 a placeholder return that was never filled in."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/JSInterop.cs"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"38ccf276ee407563c3cb7aa7547268348eca7565672448112f02f1b856e6da5a"}},{"ruleId":"IC1","level":"note","message":{"text":"Placeholder data left in code: A placeholder value (\u0022Jane Doe\u0022) is still in shipped code \u2014 sample/mock data that was never replaced with the real thing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Elements/ElementsFormsDemo.cs"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9b9c07b733609129e94a9d722907333bae7d17a3c299bbdb4d1186ce5cfc92e"}},{"ruleId":"IC1","level":"note","message":{"text":"Placeholder data left in code: A placeholder value (\u0022Jane Doe\u0022) is still in shipped code \u2014 sample/mock data that was never replaced with the real thing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Elements/ElementsFormsDemo.cs"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fb0bdd1b22c9ccb1d95a41919b22791e70ff31385a3b2c0a470832c71b02cbd"}},{"ruleId":"IC1","level":"note","message":{"text":"Placeholder data left in code: A placeholder e-mail address (\[e-mail redacted]\u0022) is still in shipped code \u2014 its domain is reserved for documentation, so anything sent here is undeliverable by construction. Replace it with the real address, or take it from configuration."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Elements/ElementsSectionsDemo.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b0e3b254015337498fb3027c39d40fb54e3de9179db2f98782085364d16aa9e"}},{"ruleId":"IC1","level":"note","message":{"text":"Placeholder data left in code: A placeholder e-mail address (\[e-mail redacted]\u0022) is still in shipped code \u2014 its domain is reserved for documentation, so anything sent here is undeliverable by construction. Replace it with the real address, or take it from configuration."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/UiKit/UiKitLayoutDemo.cs"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f18575a11b7be34d918f976f1a368ea48b654bcbf77f3983f867a36bc91cd55"}},{"ruleId":"IC1","level":"note","message":{"text":"Placeholder data left in code: A placeholder e-mail address (\[e-mail redacted]\u0022) is still in shipped code \u2014 its domain is reserved for documentation, so anything sent here is undeliverable by construction. Replace it with the real address, or take it from configuration."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskBatteryWiring.cs"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1ae0010abe3b462ede86e300f0f0792dc3dcb41ac1a07d3f3ae49f92c7e8fb8"}},{"ruleId":"IC1","level":"note","message":{"text":"Disabled test: A test is skipped (\u0022diagnostic \u2014 run manually to gather allocation deltas\u0022) \u2014 coverage that looks present but never runs in any gate. If it\u0027s an opt-in suite, document how it runs; otherwise re-enable or delete it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.Core.Tests/Performance/CounterAllocationPinTests.cs"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"459131723a2d5ae41b6d607de59f0bedda539870ea75ba3b821616ea62d16b8c"}},{"ruleId":"M2","level":"note","message":{"text":"No ADRs: No Architecture Decision Records found \u2014 no conventional ADR directory, no numbered \u0060NNNN-title\u0060 documents in any markup this check reads, and nothing ADR-shaped by content. Design rationale recorded elsewhere (a design-notes tree, a mailing list, pull-request discussion) is not visible to this check and is not re-findable per decision, so a future maintainer cannot ask why one choice was made and get an answer."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"670b3d6e36a756d63097d0dfbf90afd5fc761308800b9354894a07c3f4e4aa14"}},{"ruleId":"P12","level":"note","message":{"text":"Sleep-based test synchronization: 138 Task.Delay/Thread.Sleep call(s) in test code synchronize with background work by sleeping \u2014 a known flakiness precursor on slow runners. Prefer polling with a deadline or completion signals."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6a03a2c4f0cdb020131eedb5050e85716d2d15c3e6c049458617ddd83166de9e"}},{"ruleId":"P2","level":"note","message":{"text":"Logging is not universal: Only 20/47 service-like projects use logging (pure contract/DTO projects are excluded \u2014 they have nothing to log). Of those 47, 2 ship a process this repository operates; the rest are libraries their consumer hosts, where the logging decision belongs to the host."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"91a94e21d6d4d0e6a2003f94505b0b02b157176f0b24c4820f3f82b4447a97fe"}},{"ruleId":"P4","level":"note","message":{"text":"No rollback/health safety: Deployment automation exists and the service already exposes health probe endpoints (healthz/livez/readyz or a container healthcheck), but no manifest in this repository wires them into readiness/liveness probes, a rolling-update strategy, lifecycle hooks or a migration job \u2014 a bad release is harder to detect and reverse. If that wiring lives in a separate ops/Helm repository, document the pointer here so release safety is evidenced."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"db6bab8a28a2145f47e5a4e6683cda39d2ba0296c723238e8057da979ae1c706"}},{"ruleId":"P8","level":"warning","message":{"text":"Schema created with EnsureCreated() (no migration path): \u0060EnsureCreated()\u0060 builds the schema once and can\u0027t evolve it \u2014 there\u0027s no upgrade path for an existing production database, and it bypasses the migrations history. Adopt a versioned schema-migration mechanism (with EF Core: \u0060dotnet ef migrations add\u0060 \u002B \u0060Migrate()\u0060 on startup) so schema changes are versioned and applied safely."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/TestDatabase.cs"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ab7469359860f343e7f4d0f72c4f1b1127196b26f984a4739b805e4a5ff9838"}},{"ruleId":"PF3","level":"warning","message":{"text":"Sync-over-async blocking: 12 blocking call(s) on async work (.Wait()/.GetAwaiter().GetResult()) \u2014 these waste a thread and can deadlock wherever a synchronization context is in play (a UI thread, or a caller that has one)."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"2dedb76432d7d4f359386b5c37564c0f3de368182a77e31aa8af9ba73f9a4def"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplication concentrated across 13 sibling directories (26 clone groups): 26 duplicated blocks under src/Rask.Templates/ have copies in at least two of the sibling directories analog, angular, lit, nextjs, nuxt, preact (\u002B7 more sibling(s) not listed) \u2014 24 of them are reported below, and 2 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 26 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 26 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 26 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/src/app.tsx"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"258cfeb2e86b2df44a82d447185bc6b4b303bd5928e17b03acded6afa6bc6bc8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplication concentrated across 5 sibling directories (25 clone groups): 25 duplicated blocks under src/ have copies in at least two of the sibling directories Rask.Core, Rask.Server, Rask.Site, Rask.Templates, Rask.Wasm \u2014 19 of them are reported below, and 6 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 25 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 25 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 25 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1461}}}],"partialFingerprints":{"codehealthFindingId/v1":"8873e4a4104231d97a5598f04b73ecd9d06d28c93ee43320c6e7d31c0c355fce"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (79 identical lines \u00D7 2 files): src/Rask.Templates/preact/client/src/app.tsx:2 \u00B7 src/Rask.Templates/react/client/src/App.tsx:2 \u2014 these 2 files are line-for-line copies of one another \u2014 79 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/src/app.tsx"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"88d69325b10c7b6fffc01b0737404ca554969b44a1d7f546840f11c340f5465a"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (56 identical lines \u00D7 2 files): src/Rask.Templates/nextjs/client/app/auth-form.tsx:3 \u00B7 src/Rask.Templates/tanstack-start/client/src/components/AuthForm.tsx:1 \u2014 these 2 files are line-for-line copies of one another \u2014 56 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/nextjs/client/app/auth-form.tsx"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"537f1d74b5038785f27c23f1ddf39393cdd0f5be8cc71507129c36f0f79fad08"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (54 identical lines \u00D7 2 files): src/Rask.Templates/solid/client/src/Auth.tsx:1 \u00B7 src/Rask.Templates/solidstart/client/src/components/AuthForm.tsx:1 \u2014 these 2 files are line-for-line copies of one another \u2014 54 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solid/client/src/Auth.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6e1482dbbb084837fc7196d8d435af0a737bc200da96080bec26f3bd054a53a"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (52 identical lines \u00D7 2 files): src/Rask.Templates/nextjs/client/app/auth-form.tsx:3 \u00B7 src/Rask.Templates/react/client/src/Auth.tsx:1 \u2014 these 2 files are line-for-line copies of one another \u2014 52 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/nextjs/client/app/auth-form.tsx"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b2391d05201c5b47273b6ed5496d15ae3f0046326aa213e3bdc7ea6f321588c"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (52 identical lines \u00D7 2 files): src/Rask.Templates/preact/client/src/auth.tsx:2 \u00B7 src/Rask.Templates/react/client/src/Auth.tsx:2 \u2014 these 2 files are line-for-line copies of one another \u2014 52 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/src/auth.tsx"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"33f6179523f910fd4857a0e8f034b93ccfea17161b253f65d78f52950fa09267"}},{"ruleId":"R10","level":"warning","message":{"text":"Wholesale file copy (52 identical lines \u00D7 2 files): src/Rask.Templates/react/client/src/Auth.tsx:1 \u00B7 src/Rask.Templates/tanstack-start/client/src/components/AuthForm.tsx:1 \u2014 these 2 files are line-for-line copies of one another \u2014 52 lines are identical, in the same order, in every one of them \u2014 so this is one fact about the file set, not a block to extract. An edit made to one file and not the others changes behaviour silently, which is the failure a wholesale copy guarantees. Pick one file as the single source and derive the others from it (re-export it, spread it into the local overrides each variant genuinely needs, or generate the copies at build time) \u2014 the few lines that differ between the files are exactly the part each variant should still own. Check first whether the copies are deliberately standalone deliverables (a translation file seeded from its sibling and waiting to be translated); where they are, the duplication is the design, and the honest move is to mark the seeded file as untranslated rather than to let it pass as done."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/react/client/src/Auth.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b25b466677e75c73ddc492eaf09c936f906dd71ac851981751eb784ecd236e6e"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (39 lines \u00D7 2 locations): src/Rask.Templates/svelte/client/eslint.config.mjs:13 \u00B7 src/Rask.Templates/sveltekit/client/eslint.config.mjs:13 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/svelte/client/eslint.config.mjs"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a7ea4106bc0b47691c3098a90534e84162105558cafdc4c4488447164086714"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2 locations): src/Rask.Templates/nuxt/client/eslint.config.mjs:13 \u00B7 src/Rask.Templates/vue/client/eslint.config.mjs:13 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/nuxt/client/eslint.config.mjs"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"f79f1cb0a364f876ec5f34814f56a8ac5b0f82c0256d1462a51638b6e264e2d4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 3 locations): src/Rask.Templates/preact/client/eslint.config.mjs:13 \u00B7 src/Rask.Templates/react/client/eslint.config.mjs:13 \u00B7 src/Rask.Templates/tanstack-start/client/eslint.config.mjs:13 \u2014 the 3 copies are spread across 3 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/eslint.config.mjs"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf926578d483f824d6d4b29f9fe59726e05d956542f8e8f27f17c2d842064ac4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (34 matched lines \u00D7 2 locations): src/Rask.Core/Resources/browser/deviceMotion.ts:40 \u00B7 src/Rask.Core/Resources/browser/deviceOrientation.ts:51 \u2014 the two spans are one implementation copied and then locally edited \u2014 215 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/deviceMotion.ts"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"63f20595c8439829f4efa3541222d711138eee9687253e17f375eadaf160b1e6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (32 lines \u00D7 2 locations): src/Rask.Templates/solid/client/eslint.config.mjs:13 \u00B7 src/Rask.Templates/solidstart/client/eslint.config.mjs:13 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solid/client/eslint.config.mjs"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f98fd7e769a18c691a2ed6138274844cb5b9f02df726969b37cbaf716d054ba"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 3 locations): src/Rask.Templates/analog/client/eslint.config.mjs:12 \u00B7 src/Rask.Templates/angular/client/eslint.config.mjs:12 \u00B7 src/Rask.Templates/nextjs/client/eslint.config.mjs:12 \u2014 the 3 copies are spread across 3 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/eslint.config.mjs"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"8630b930a94db549bd3e43dbfb82210f764e7fa720ba1cb5d4ca2123e3f38ca9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 3 locations): src/Rask.Templates/preact/client/src/app.tsx:35 \u00B7 src/Rask.Templates/react/client/src/App.tsx:39 \u00B7 src/Rask.Templates/solid/client/src/App.tsx:19 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is a DECLARATION HEADER \u2014 the name, parameter list with its constraints and defaults, and base-type clause of a declaration \u2014 rather than statements inside a body. A header cannot be lifted into a helper: there is no expression position for a call to stand in, and the copies are frequently required to match, because one declaration passes its parameters straight through to the other. So the move is not extraction. Give the repeated pieces names \u2014 factor a long constraint or base-type expression into one named type both declarations refer to \u2014 and where the headers must stay identical, derive one from the other (a shared base declaration, or a single alias that spells the parameter set once) so that changing it once changes both. Where the language offers neither, treat the two as a pair that must be edited together: they drift apart the first time only one of them is changed, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/src/app.tsx"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2da1b97ae5565b6ee54c94c34e5b1cb23c44fc80502800649cfa56d6304c0b0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 7 locations): src/Rask.Templates/angular/client/src/push.ts:20 \u00B7 src/Rask.Templates/lit/client/src/push.ts:20 \u00B7 src/Rask.Templates/preact/client/src/push.ts:20 \u00B7 src/Rask.Templates/react/client/src/push.ts:20 \u00B7 \u002B3 more site(s) not listed \u2014 the 7 copies are spread across 7 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 7 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/angular/client/src/push.ts"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"9df8fe3c40c4f0f975248f43734c168d66cc8f3e2fff86cb82b39047c94cfb03"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2 locations): src/Rask.Server/Resources/rask.ts:1461 \u00B7 src/Rask.Wasm/Resources/rask.wasm.ts:641 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1461}}}],"partialFingerprints":{"codehealthFindingId/v1":"86bc1b1106ee1493d36ddd40c3cc8fab76a79cf0d0ba6c297961f5b34092ddc5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2 locations): src/Rask.Wasm/Resources/rask-wasm-api.ts:302 \u00B7 src/Rask.Wasm/Resources/rask-wasm-api.ts:439 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4fb5f037d8f6c3c5347f99982b046f49f2f0bb4b9338dcb41041d2745c5e7cd"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (22 matched lines \u00D7 2 locations): src/Rask.Templates/svelte/client/src/lib/Greeting.svelte:7 \u00B7 src/Rask.Templates/vue/client/src/App.vue:8 \u2014 the two spans are one implementation copied and then locally edited \u2014 134 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/svelte/client/src/lib/Greeting.svelte"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"1925f5742b041335bb709cb22b958baeb0d63af23a988a59fe3cc2eb62dc1b22"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): src/Rask.Server/Resources/rask.ts:1955 \u00B7 src/Rask.Wasm/Resources/rask.wasm.ts:1000 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1955}}}],"partialFingerprints":{"codehealthFindingId/v1":"ceac39da84450f2ef8d037af504722d27bd39eabde18b165f273deaa81c88272"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): src/Rask.Server/Resources/rask.ts:1674 \u00B7 src/Rask.Wasm/Resources/rask.wasm.ts:763 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1674}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9b1e511966d42117abdc27b0ac61f61aa3b17e3a47a8592f35166f4a2ed12e0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2 locations): src/Rask.Templates/analog/client/src/app/pages/auth-form.ts:68 \u00B7 src/Rask.Templates/angular/client/src/app/auth.ts:71 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/auth-form.ts"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"5107c78bc9df1ffee75c2847c48b4a61cefc82e46f1443a88a269bf90b490365"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 7 locations): src/Rask.Templates/angular/client/public/rask-sw.js:4 \u00B7 src/Rask.Templates/lit/client/public/rask-sw.js:4 \u00B7 src/Rask.Templates/preact/client/public/rask-sw.js:4 \u00B7 src/Rask.Templates/react/client/public/rask-sw.js:4 \u00B7 \u002B3 more site(s) not listed \u2014 the 7 copies are spread across 7 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another. There is one copy in each of 7 separate files rather than several in one place, so check first whether these are sibling modules that each declare their own version of one shape \u2014 one per entity, per provider, per language. Where they are, no single extracted module collapses them: each module still has to be written, and what recurs is the TEMPLATE. The moves that do collapse a template are to generate these modules from the set they enumerate, or to replace the repeated construction with one factory each site calls with its own values \u2014 and where the set is the point, each module pinning one distinct thing, the repetition IS the enumeration and there is nothing to delete."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/angular/client/public/rask-sw.js"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc33eb34cde432c5adcdec24e97d11c84e1eeaa21443cb9aeb922c012c9143b8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): src/Rask.Wasm/Resources/rask-wasm-api.ts:504 \u00B7 src/Rask.Wasm/Resources/rask-wasm-api.ts:710 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":504}}}],"partialFingerprints":{"codehealthFindingId/v1":"02c4bc340fa9c49e682476636e5bb151d908ea6a076e2c5d39387896ec8c3d36"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): src/Rask.Server/Resources/rask.ts:1362 \u00B7 src/Rask.Wasm/Resources/rask.wasm.ts:157 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1362}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0643795f28511368911869d8f266446843c0d05beb7579bd4322caca17e1ee4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): src/Rask.Templates/_islands/preact/Features/Islands/Preact/PreactCounter.tsx:5 \u00B7 src/Rask.Templates/_islands/react/Features/Islands/React/ReactCounter.tsx:5 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/preact/Features/Islands/Preact/PreactCounter.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf71ecc43d7863970a9ee34e5d2dcdb455c96b0c1e93eac7c12f8ca5f7c65f1c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): src/Rask.Core/Resources/browser/auth.ts:213 \u00B7 src/Rask.Core/Resources/browser/auth.ts:283 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/auth.ts"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e3c3ce8c0f68af06c2e680cc2b1cfe1d09c6892eec760ac697f69f9144318df"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 3 locations): src/Rask.Core/Resources/browser/globals.ts:719 \u00B7 src/Rask.Core/Resources/browser/globals.ts:771 \u00B7 src/Rask.Core/Resources/browser/globals.ts:793 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/globals.ts"},"region":{"startLine":719}}}],"partialFingerprints":{"codehealthFindingId/v1":"09237d3cff473fdb5c8dfa3e15e9ae301341e5e4eb932d8802ddd49f762b31b6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): src/Rask.Server/Resources/rask.ts:1775 \u00B7 src/Rask.Wasm/Resources/rask.wasm.ts:852 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1775}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e8f46bd2fc439ef8d1e73328180ec2d2b7ad4da806d6f7b0cc7f66d995960a5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 7 locations): src/Rask.Core/Resources/browser/globals.ts:377 \u00B7 src/Rask.Core/Resources/browser/globals.ts:444 \u00B7 src/Rask.Core/Resources/rask-api.ts:64 \u00B7 src/Rask.Wasm/Resources/rask-wasm-api.ts:135 \u00B7 \u002B3 more site(s) not listed \u2014 the 3 copies are spread across 3 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/globals.ts"},"region":{"startLine":377}}}],"partialFingerprints":{"codehealthFindingId/v1":"afe7b501eb7aa1ca688a68d28e1d3ea6ab91e25b59047cf4ec93abebd061f589"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 3 locations): src/Rask.Site/Features/Islands/React/ReactCounter.tsx:13 \u00B7 src/Rask.Templates/_islands/preact/Features/Islands/Preact/PreactCounter.tsx:5 \u00B7 src/Rask.Templates/_islands/react/Features/Islands/React/ReactCounter.tsx:5 \u2014 the 3 copies are spread across 3 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Islands/React/ReactCounter.tsx"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"d849ae651eed8896c8014e4c8a16262c80fdbc67c47bce13ef617cef14cb4189"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2 locations): src/Rask.Wasm/Resources/rask-wasm-api.ts:366 \u00B7 src/Rask.Wasm/Resources/rask-wasm-api.ts:478 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd5e944bbc17d6b9873a383a422805d3997bc299b0e778aef3ac011f9efb32ab"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): src/Rask.External/client/preact.ts:45 \u00B7 src/Rask.External/client/react.ts:42 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/preact.ts"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dd45121d331b17c0bcfdec6a9883cef93c53bf9e17463b2ff3663e2486268d8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): src/Rask.Wasm/Resources/rask-wasm-api.ts:246 \u00B7 src/Rask.Wasm/Resources/rask-wasm-api.ts:378 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"efc0dfa86854b718761123e992ef801ad900d868be0e3630f7b3f880cd5832b9"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (12 matched lines \u00D7 2 locations): src/Rask.Core/Resources/rask-dom-path.ts:70 \u00B7 src/Rask.Core/Resources/rask-dom.ts:60 \u2014 the two spans are one implementation copied and then locally edited \u2014 83 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom-path.ts"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d35aea3f3b314dddf857ed83e06f0b750f234984eb34d2e5d9c86b28ed40dd1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): src/Rask.Templates/solidstart/client/src/routes/about.tsx:4 \u00B7 src/Rask.Templates/solidstart/client/src/routes/index.tsx:4 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a DECLARATION HEADER \u2014 the name, parameter list with its constraints and defaults, and base-type clause of a declaration \u2014 rather than statements inside a body. A header cannot be lifted into a helper: there is no expression position for a call to stand in, and the copies are frequently required to match, because one declaration passes its parameters straight through to the other. So the move is not extraction. Give the repeated pieces names \u2014 factor a long constraint or base-type expression into one named type both declarations refer to \u2014 and where the headers must stay identical, derive one from the other (a shared base declaration, or a single alias that spells the parameter set once) so that changing it once changes both. Where the language offers neither, treat the two as a pair that must be edited together: they drift apart the first time only one of them is changed, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solidstart/client/src/routes/about.tsx"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"a04262ccae348447605b1e26da2d9aff761f96c80844b272dd45b416d92dfce3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2 locations): src/Rask.Templates/svelte/client/src/lib/Auth.svelte:17 \u00B7 src/Rask.Templates/sveltekit/client/src/lib/AuthForm.svelte:17 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/svelte/client/src/lib/Auth.svelte"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"e27274674e1b49ab9c8e3d55c08aa5451f3514a6fcc334006437d9528150fbfc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): src/Rask.Core/Resources/rask-dom.ts:463 \u00B7 src/Rask.Core/Resources/rask-dom.ts:646 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"bba1eda500079b05af28645aafebcc4698b6fb2735a5887818561aee8140da5f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): src/Rask.Server/Resources/rask.ts:1573 \u00B7 src/Rask.Wasm/Resources/rask.wasm.ts:214 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1573}}}],"partialFingerprints":{"codehealthFindingId/v1":"b03fc18db15d4658c36e667177010f9a8d7c2e22ebd4d7e8affaa7374ca849ca"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): src/Rask.Server/Resources/rask.ts:1894 \u00B7 src/Rask.Wasm/Resources/rask.wasm.ts:908 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1894}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c12228ec570c408d8be682e06a5368381a2595501098454a0c07acc74c1408d"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function morph (cyclomatic 74, cognitive 132): morph has cyclomatic complexity 74 and cognitive complexity 132; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"a79b32369dbc3a3310bc68dc470bd4f2dcaec7d3e24cec33ff95934efe67f790"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function serialize (cyclomatic 38, cognitive 39): serialize has cyclomatic complexity 38 and cognitive complexity 39; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":499}}}],"partialFingerprints":{"codehealthFindingId/v1":"6671e564a9181ddd9b904a941930624620d50e4e835596c5d728417acce63cf4"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function applyDiff (cyclomatic 34, cognitive 71): applyDiff has cyclomatic complexity 34 and cognitive complexity 71; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"492adffe70a0f46a50660c4e41cad696043f1ac479620fcf970bdc8f77b3d182"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function extractIsland (cyclomatic 29, cognitive 46): extractIsland has cyclomatic complexity 29 and cognitive complexity 46; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8da44daa5e13b5041f72f02c7adb5b0426512ebc718a080156561bf97c3bff6"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function extractAngular (cyclomatic 26, cognitive 41): extractAngular has cyclomatic complexity 26 and cognitive complexity 41; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":1188}}}],"partialFingerprints":{"codehealthFindingId/v1":"9244456aabb4144883317ac345af0012dabc24dd19d7eddf35a351256ca95f9a"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function renderChildren (cyclomatic 26, cognitive 39): renderChildren has cyclomatic complexity 26 and cognitive complexity 39; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/angular.ts"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"705a757c99b5b30ad351d86f40f9b8158661ced0ee58c4f5985dcc9ee40cdbda"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function renderChildren (cyclomatic 25, cognitive 37): renderChildren has cyclomatic complexity 25 and cognitive complexity 37; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/lit.ts"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b40c2b14fda77a24bf1948e46d662ec8a05dbd4e47e4923c48d9b7e461218b4"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function extractLit (cyclomatic 25, cognitive 36): extractLit has cyclomatic complexity 25 and cognitive complexity 36; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":941}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e087c2c301816afc44779e6b69d0e54a81014cc0a2de9bdea848413e937e0f6"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function commit (cyclomatic 22, cognitive 28): commit has cyclomatic complexity 22 and cognitive complexity 28; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1496}}}],"partialFingerprints":{"codehealthFindingId/v1":"d441e9ba1f7f799d95676d0431fdbe2bed09efd422f9e9cbcca764304c80a500"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function showDevError (cyclomatic 20, cognitive 21): showDevError has cyclomatic complexity 20 and cognitive complexity 21; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-deverror.ts"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"4329be794c5c69d39a0d9ea9ea963faeb7d54ebc1dea132a7fcd9d00aac1ceae"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function onFrame (cyclomatic 19, cognitive 22): onFrame has cyclomatic complexity 19 and cognitive complexity 22; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"70430d6199b693b89d594dc786a67f863dbbd9e2d77014c59481018542b78690"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function trackHeadAsset (cyclomatic 19, cognitive 17): trackHeadAsset has cyclomatic complexity 19 and cognitive complexity 17; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask.wasm.ts"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac4da554a89568537d03177be83ec86a2f0907c34350cbf91b968f91c8df609d"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function applyManifest (cyclomatic 18, cognitive 25): applyManifest has cyclomatic complexity 18 and cognitive complexity 25; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"25e2d86d3c26bc8ab3c906790ed589a08d53f61574abf433aa43c771683995cf"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 18, cognitive 18): (anonymous) has cyclomatic complexity 18 and cognitive complexity 18; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-dom.ts"},"region":{"startLine":901}}}],"partialFingerprints":{"codehealthFindingId/v1":"5821a32721886f5eb3a24e0466e53d7ee48db7389d3cbbb9cdb42898a611af5b"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function raskNotePendingFormState (cyclomatic 17, cognitive 23): raskNotePendingFormState has cyclomatic complexity 17 and cognitive complexity 23; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-morph.ts"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"e265b1ba3d074893360bcde37668e4ac62914223153d4fb6ec6ee901ddcb9be0"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 16, cognitive 12): (anonymous) has cyclomatic complexity 16 and cognitive complexity 12; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/panel/panel-client.ts"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff7781fdf5887a64b6743fc7d4e15c04e26d4e963cb68f23d8b7994f0478fe42"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 15, cognitive 26): (anonymous) has cyclomatic complexity 15 and cognitive complexity 26; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask-http-transport.ts"},"region":{"startLine":356}}}],"partialFingerprints":{"codehealthFindingId/v1":"e51ab2c46aa89fbdf6b55b3b9892debfbb7968acceb0e4abfeb5fc3fd0c383b3"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function handle (cyclomatic 15, cognitive 21): handle has cyclomatic complexity 15 and cognitive complexity 21; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/host/bridge.ts"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"13c6d6323275e6020388b09e837e85485c85f536ed97282215f5c97f0fa0ea19"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function saveRestoreFields (cyclomatic 15, cognitive 21): saveRestoreFields has cyclomatic complexity 15 and cognitive complexity 21; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":778}}}],"partialFingerprints":{"codehealthFindingId/v1":"da3045ee4f22f140311aaad5bc9d47c7a4926c05e1c7ab767a6cc96088328dc8"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 15, cognitive 20): (anonymous) has cyclomatic complexity 15 and cognitive complexity 20; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-events.ts"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bffa37b6e3d87fc91c272cbab85a384d8316ef2222d297c0a89d86e2fcbc421"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/Resources/rask.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"61d8972aa466a8eb53dc8d2fc1cee77a944cd703311ca9a8c6c89e182ccc13b9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8add820841226e854d04423747b8e87618e8a1941aa543bd554a4c26adbdc33"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask.wasm.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bd707a935eb6c4a4b80633dd24b85b0b23ba6a25dda4463ca7d8b4b11e994e9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/globals.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"20d04f75f0f64137ffe484044631c7bb8baee3209dee016cb9ab1ab6cc940fff"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Resources/rask-wasm-api.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e9b3c658f715a68d441c224e15ed1c6646aac6ae5d3ba9ef937564a1c68908c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/client/client.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3ae14cbb4af2534fc554ff91b2000df7647a3c3c4ee6dc073bdb8a104eb9fd2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-api.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f7df4a87c2368bbdb2a9d0f67a093cdf5d9469f17ae17123f0280fdcb681453"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-deverror.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d94ed43f2b2c5d444763c0276256811797629124c805695ca5c382d32e4a56c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/angular.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd9940a5f495cd0f8c4b1030d7ed516b89eeea6e1bdb07afd3bb82ba9f475459"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/Browser/main.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf820d7550418b648d8d57a79f3e7375ef75c06affe2b9742a6c42c98973c9ee"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/analog-welcome.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d94eb92ca49284fc162ca9685054946ff04f1160e886bb9b289ca16f14b555da"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/lit/client/src/my-element.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"498f4ed3ac0362d37336cfed1d7fc11c1c597da425cff4f18274e92751cbecd1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/webAuthn.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4c429e578c96678a70142df37a4a3a45797bd14c87339bc71d29a4f8591b1af"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/originPrivateFileSystem.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"112e819a3582fd70d48df9d40084be9d709f675c5f293dc459e66935cbdbfddc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/fileSystem.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ce384151fe4ba1edb41de502c0f1686cd6c568361171c8934a33dbecec71032"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/speechRecognition.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b4ca80128a3c87139e92688b1ba717490265878b2642618150f571b7cbc618"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Shared/GuideChrome.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab9b032d6e60a8c77d215213b034c4d9eb4cfd562310e9bc9040dde5e3ca55da"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/capture-devtools-screenshots.mjs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7eb06181f2997f1b483d25ba7f020bde6628d5d6d71b064b06cbc3b35dfc9405"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/react/client/src/App.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dffb439147d7f85ec80f4f20790cb7908d56dc52825a1936bf2626cb3137d74"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/battery.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eafba40633516e20c3a6fe6cfbc11a22ec94583b43e787954e94b23bd829ec06"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/src/app.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"967be9f45f5c336b73b6b417a03a4ea3b2757471195ce92e35590b40b006b6fa"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/webPush.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c1ba8deff6d06f66938e3e4924585630673273643e40f678fc89329dbc43ba1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solid/client/src/App.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ef82b9673cec652a6caa0676697261186cb637514c81308b0b1b9ec8a81847c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Features/Islands/LitBadge.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e269109bc3d723c8bbb7f04d8be26733d60ee03adb5883caa13af1583a6ed6eb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/gamepad.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"54b2ed2da29e736376e7b49a84f433a76a84d18efd7eb7fd469aa64ab37ede73"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/signaling.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"57194def2c07dfd14cdd1c4f456fa3dcaed2a6e8ac302566437858a3276a493d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/auth-form.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"90df8416a000d82c9b29e3afc97dbac14655df0d21eebc7a3bcc4b02946a658c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/deviceMotion.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab6c84662b2baf559f3d32bd67f7ac828ecbedf464fe38e51b6d56fe2730f62f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/wakeLock.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a752a582cd25a71d5ce820b5a3aab9af490124d20d2d06b7f6a0c5f364b77c4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/deviceOrientation.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7970a6382d23622121751d1ae3f61e40f7ee24dfecc753fcd95fc93e2d58d2ec"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.DevTools/Resources/rask-devtools-wasm.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"11e30f17d415b5e995e1898d5894fd34f77b6f3dd8231a859cd6adc1b9f469fb"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/react/client/src/Auth.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"45ce60d67883bfe9d5858431ee05d7502e10bd050eb7d49b66d1bbfb4e1ed814"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/rask-scoped.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"770a8bc91a9a54d607c5fe54fc775f3bc6f2ff54768f0dd2ab501888d145ee3f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/nextjs/client/app/auth-form.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f699e9a8517582cbfa97c267743ec0a810828773be4dbecbab5b40c465a5142c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solidstart/client/src/components/AuthForm.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a168b9e4e4addbca7f971df23f9fe22118ca754efa2e8bbbeda31b670b87f107"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/installPrompt.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b47b501be7629c10ce20007ef3334e9000c0da3a2b22143f0b00b23eb3b2f4a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solid/client/src/Auth.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"921422fa4a3b7b9673def8613a8b2d99a6981614708486541c086f174881fe15"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/src/auth.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"278c440b3aebb1016b435a2e3be727c25e187f8b2dfd28ebc9b08606735f887d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/tanstack-start/client/src/components/AuthForm.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"027a48dff6018ff02e847e61399b9aa9e5cd2576eb0408fa65eea747d6add761"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/indexedDb.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"52dbaceb6979b0a59edd3943a2f580b96aa5eae60c4662a9fd4f78fa5a81c39b"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~578 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), but 1 in-repo import(s) from 1 other file(s) do name it (src/Rask.Spa.Hosting/client/query.ts) \u2014 every one of those referrers is itself unreachable, so this file is dead only as a member of that cluster: if any referrer is in fact alive, this row falls with it"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/client/client.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"622a617b6327eb6b069f4698dc4508e622bed02f6112ccc08f514e349753fed6"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~341 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/angular.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea2852977a6bfc213a948efa9d7e7569b13f9ec74f7a3433203882ecc5edf69e"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~271 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), but 1 in-repo import(s) from 1 other file(s) do name it (src/Rask.Templates/analog/client/src/app/pages/index.page.ts) \u2014 every one of those referrers is itself unreachable, so this file is dead only as a member of that cluster: if any referrer is in fact alive, this row falls with it"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/analog-welcome.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"66dcfc199b95a281703d3e931e1310dce36b7c1ec7a65d8b7f6ce2d6ecc233bf"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~91 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), but 2 in-repo import(s) from 2 other file(s) do name it (src/Rask.Templates/analog/client/src/app/pages/login.page.ts, src/Rask.Templates/analog/client/src/app/pages/register.page.ts) \u2014 every one of those referrers is itself unreachable, so this file is dead only as a member of that cluster: if any referrer is in fact alive, this row falls with it"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/auth-form.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf360e0cded328015541098fe0eab32cc45bd51d4f844f90aab747164ec4fde7"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~85 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), but 2 in-repo import(s) from 2 other file(s) do name it (src/Rask.Templates/solidstart/client/src/routes/login.tsx, src/Rask.Templates/solidstart/client/src/routes/register.tsx) \u2014 every one of those referrers is itself unreachable, so this file is dead only as a member of that cluster: if any referrer is in fact alive, this row falls with it"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solidstart/client/src/components/AuthForm.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc0ec8ae6e4d9990640d47172ba3199888bc8da1c5d7dae1656fb9ac449cdffe"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~75 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/svelte.svelte.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"558fc3efd65998c9b8a8af0b93b23ac7c0b441c4e285741ed5172f56229f3ce7"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~72 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Spa.Hosting/client/query.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"26ee95acc6f8c7883b970eb45e730e50e31971939e05617455f390f105d5830b"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~69 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/angular/client/src/push.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9e03940dc1a325aacca27747857ec489bb96af976019f4f0c6c2a79b3ef53d2"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~69 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/preact/client/src/push.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"542d8fb16142f1b5bcdc8a915d78e07e9884a60246e3a803249979ac5476829c"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~69 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/react/client/src/push.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"796221118d1bc06ae17c206890f5ffeca3247088486706f99bf111af4e87566c"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~69 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solid/client/src/push.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a190fe317accbbf19f274989a37f6c72a7bff492cec3027be013aebf0879d9a"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~69 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/svelte/client/src/push.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"86bd8f3c4c1b09f126307deca5410a125b21d6d22dacd09e9c8830d21b74998a"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~69 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/vue/client/src/push.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7500483cddcb69f93cdb9366fdbac26560fbffd9dc72d6d8d5602df9ddf2aa0"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~54 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Resources/browser/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9afb32bd68320fdc6c39abc4adaae0062e26871d40aece98a6cab07e10e23166"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~33 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/lit/Features/Islands/Lit/LitBadge.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad175a41e671c1aae60250a85b933785a1580c7b67af18da2ca14f96e120785f"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~29 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/angular/Features/Islands/Angular/AngularCounter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"435ca3f2afe95af4528cf45ab548324edab03a39e0e028a83440400e642299fa"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~29 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/nuxt/client/app/components/AuthForm.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4aa27b274602404899c975b30fb12b618af6620c23c604601c898ef4bc75e1f"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~28 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/sveltekit/client/src/lib/AuthForm.svelte"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cc46a948f1ff45be2de3153a3c868eb66f4ef6c46aa6986d6da68c1e7b2cddb"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~25 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solidstart/client/src/routes/[...404].tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"21fd986b59944b27be570e64bf91b5e5c96b5e32b8aa1c7604a9bf0de5aa3c29"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~25 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solidstart/client/src/routes/index.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"db734fe50aa68cb74487726766832f361e58d97be4b49ec83f5f823e309f1c85"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~24 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/preact/Features/Islands/Preact/PreactCounter.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d6a346465848d3099a572dba980332ac190977d504248f9a19dbab6e2329a6d"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~24 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/react/Features/Islands/React/ReactCounter.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8ec51ff6248d20b366dd29cf72cdf1bd9678a3b5fea8b9406437e78f80e77af"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~24 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/solid/Features/Islands/Solid/SolidCounter.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"865192f5d410f213f8ca91757a7b1c1619aa54748261feebe30231a18a85f593"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~12 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), but 1 in-repo import(s) from 1 other file(s) do name it (src/Rask.External/client/svelte.svelte.ts) \u2014 every one of those referrers is itself unreachable, so this file is dead only as a member of that cluster: if any referrer is in fact alive, this row falls with it"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/RaskHost.svelte"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"af15a70931902c30d5a498a7bdccb0dabdcf237122ad39a0ec35d093cf53b8f4"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~12 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), but 1 in-repo import(s) from 1 other file(s) do name it (src/Rask.External/client/RaskHost.svelte) \u2014 every one of those referrers is itself unreachable, so this file is dead only as a member of that cluster: if any referrer is in fact alive, this row falls with it"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/RaskTree.svelte"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"56308afae7083cfba8f1f35cb1deaed8a18f2252ec90899cbbc5fac65393bc48"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~10 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/svelte/Features/Islands/Svelte/SvelteCounter.svelte"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1b871d60acf8a5252af2d2572bfff3fbede40de1fac724319ae190eafe046d4"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~10 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/index.page.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c3461db061e996403f51ef9ff286fc170a21462674f29d750008000ff8a33f4"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~10 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/login.page.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6404d64e2d0b8104aacc15ce4dd508e3541c037cdb54176b8eee75a39e59833"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~10 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/app/pages/register.page.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fbb79f343da7d89edee7d4560255207c63f2eda423630483769702ee59b9842"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~9 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/_islands/vue/Features/Islands/Vue/VueCounter.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e46b7bd21c434bf88e2c9e50135f70c1c0aad42f50c7f5fa910aa4fb1fee98f"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~7 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/vue/client/src/components/HelloWorld.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"27a6fc56d211f03d8fa133fab48b02c49929d5d95ddb9f00cfb52604965ef55d"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~5 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solidstart/client/src/routes/login.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3336c59afe79d3e0308b888f191767cc1509a9eb553f27bafe9e2720965feeb9"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~5 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/solidstart/client/src/routes/register.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"46748a0e1d5fee30082f795f923f0c3bd00e14febc285de0374eb2f9ce998d0e"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~5 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/svelte/client/src/lib/Counter.svelte"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbfa6ecb42b93fb5fe915d7df256e7987e4be454c589325607dbc08ef43904c5"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~3 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/analog/client/src/server/routes/api/v1/hello.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcfe1cd0e2fd1c00a2855865c93bf4dd7afe3bd6f391696817cb7c95ab82d492"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~0 LoC): no import path from any entry point (50 application, 70 tooling, 54 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Templates/nuxt/client/app/app.vue"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3739bf2ce711b254d4c88c904598e4852ec1564a23fbec2f7535b3a528af9d43"}},{"ruleId":"R8","level":"error","message":{"text":"Unlisted import \u0027preact\u0027: Imported but not declared in any reachable package.json \u2014 installs work only by hoisting accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/preact.ts"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ae7d5fa2b017ef34eb478162b6ed49fb3f8e6176d7a5b083c5b594f1bcf4f09"}},{"ruleId":"R8","level":"error","message":{"text":"Unlisted import \u0027react\u0027: Imported but not declared in any reachable package.json \u2014 installs work only by hoisting accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/react.ts"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a5b662f7c0104d2757e38825b29337ec40628ed6a9e1e6cab0bbcff880fcdfe"}},{"ruleId":"R8","level":"error","message":{"text":"Unlisted import \u0027react-dom\u0027: Imported but not declared in any reachable package.json \u2014 installs work only by hoisting accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/react.ts"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"f02108b0ce9fd88a2ab62d66874306751ba246cd8e59248c3f1a04ff68e9df62"}},{"ruleId":"R8","level":"error","message":{"text":"Unlisted import \u0027solid-js\u0027: Imported but not declared in any reachable package.json \u2014 installs work only by hoisting accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/solid.ts"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1e35c7a8cc8b6e155f1ca90b21a734c440be4cb5e13586e8efc981d51aaf6e3"}},{"ruleId":"R8","level":"warning","message":{"text":"Unlisted import \u0027typescript\u0027: Imported only as a TYPE and declared in no reachable package.json. The import is erased at compile time, so nothing is installed and no runtime resolution depends on it \u2014 but type-checking a clean clone will fail. Declare the typings it resolves through (or the package itself) in the owning package.json."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/extractor/extract-props.ts"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"da198afb0173a64eddee58968613f571f9c7d4ff2fc6d66dbfceb75316c98c5f"}},{"ruleId":"R8","level":"warning","message":{"text":"Unlisted import \u0027react\u0027: Imported only as a TYPE and declared in no reachable package.json. The import is erased at compile time, so nothing is installed and no runtime resolution depends on it \u2014 but type-checking a clean clone will fail. Declare the typings it resolves through (or the package itself) in the owning package.json."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"tests/Rask.External.Tasks.Tests/ExtractorFixtures/modules/fixture-button/index.d.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"0063902563be2a62276e51713836e2213e1c029e906c83f0773e1fb8c3d3c2fa"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027react-colorful\u0027: Declared in src/Rask.Site/package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"3cb4418fa6ca5f24f840082be861c3fa2fdb09ae242847efd3f25ef02fd709c1"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027svelte-check\u0027: Declared in src/Rask.Site/package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"015b31a12fe14cf11884b52adc5576ed9a2e920aa955d8765ca867bda5003431"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027vue-tsc\u0027: Declared in src/Rask.Site/package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"3a518bb70ec67b3cace787fd1350107de9020a0a230c7d07d32581efda433379"}},{"ruleId":"R9","level":"error","message":{"text":"Import cycle (1 files): src/Rask.External/client/RaskTree.svelte \u2192 src/Rask.External/client/RaskTree.svelte"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External/client/RaskTree.svelte"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4de3ae8f6d9934c337fada5c12cb30e5374797332c70bc9fbf790fe31ac301eb"}},{"ruleId":"S1","level":"error","message":{"text":"Cryptographic key material is a compile-time constant: \u0060SaltBytes\u0060 is the key-derivation salt and is a compile-time constant, so the secret this operation depends on is published with the source. A key that ships with the source is not secret: every contributor, fork, mirror and released binary carries it, so anyone holding the repository can decrypt what any installation encrypted, and there is no way to invalidate what was already protected because every deployment built from this source shares the value. Where the constant is a password salt the consequence differs but is no smaller \u2014 one global salt means precomputation amortises across every installation, which is the property salting exists to destroy. Read the value from configuration, an environment variable or a secrets manager at startup and FAIL FAST when it is absent, so a missing key stops the process instead of silently falling back to a shared default; treat the committed value as disclosed and rotate it rather than only deleting the line. For a salt, generate a fresh random one per password and store it alongside the hash. This repository constructs key or salt material fixed at compile time at 2 sites, not one: \u0060src/Rask.Auth.Api/PasswordHasher.cs:61\u0060 (key-derivation salt, \u0060SaltBytes\u0060), \u0060src/Rask.DevTools/Endpoints/DevToolsPanelTokens.cs:24\u0060 (MAC key, \u0060TokenBytes\u0060). Each is a separate decision \u2014 fixing only the line this row cites leaves the others in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Auth.Api/PasswordHasher.cs"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e9550183172ab170390c305f32aa3dc1e2821bc3bf58b1ace02138f095af0b0"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cache/RaskDistributedCache.cs"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"13dd4919bb2497af078758b0265ab22c6415f6cc6c4ac106d360aa2708d0dde4"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cache/RaskDistributedCache.cs"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f07dd4bb9b9a8a96884b1561c034efd1315a58b6bd49b4edbeb17b733017f9a"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cache/RaskDistributedCache.cs"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf567c6cec76fbe9e224902036a5d19c0f12fa424d926dcf11395ff110e89692"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cache/RaskDistributedCache.cs"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"c107bb516fa9c31cfe7f0696ea4730d09b2819dfdfa78a62d302e583f454a218"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Live/HandlerSyncContext.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"0463474b8a566b11709044e9017f44b3ba2e31ef4216914d8439ffb7b5f43170"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Data/DomainEventInterceptor.cs"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee9ac70f3c5ca5f9f3f364afd30ea1f60edd6161365ec2640ae8389b65596b76"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Storage/Backends/RemoteBlobBackend.cs"},"region":{"startLine":352}}}],"partialFingerprints":{"codehealthFindingId/v1":"694168fc8a06c582f3f404ca82fe093c13a15d582a64a7d81bec28631031f43c"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Tailwind.Tasks/ResolveTailwindCliTask.cs"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"989133c3811a6e55a57a2d5f43e7a847422fb48aeaf65c02ee191916cb8f0a7a"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Tailwind.Tasks/ResolveTailwindCliTask.cs"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"910fd994b6e407c1a9c97d2cf4e43f84fadfea12fcb6ba0598a3dfdd295e4d75"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.TypeScript.Tasks/ResolveTypeScriptToolTask.cs"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e43fecb4b54868410e7cec3f747409daf8cdfff60a564d909eb21cc0bd9deed"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.TypeScript.Tasks/ResolveTypeScriptToolTask.cs"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"410932a92a2e320575ba957e99099b4e3c88851c4c55e341532f6f9059c4fff9"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk): Blocking on a Task with \u0060.Wait()\u0060/\u0060.GetAwaiter().GetResult()\u0060 can deadlock (and wastes a thread). Prefer awaiting it: make the caller \u0060async\u0060 and \u0060await\u0060 instead. Where a synchronous entry point must stay \u2014 a public sync API you cannot break, or a process entry point that must not return until the work finishes \u2014 the block belongs in ONE documented bridge and never inside code that is already async; and where it already is that bridge, give the wait a TIMEOUT so a hung task fails the call instead of hanging the process."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask/RaskApp.cs"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"e525212274b330e333e72b82deb59093b338143b003f4ee6f5387d3109ef7066"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060!string.IsNullOrEmpty(path) \u0026\u0026 path.EndsWith(\u0022.cs\u0022, StringComparison.OrdinalIgnoreCase)\u0060 appears character-identically in 2 files \u2014 src/Rask.External.Tasks/FindExternalIslandsTask.cs, src/Rask.External.Tasks/FindExternalPackageIslandsTask.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/FindExternalIslandsTask.cs"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"c26e5ff34950d1123799dc0497e22352ba0cbcaa8fb76e376cec83b476c9d5ce"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060controller.Name.EndsWith(\u0022Controller\u0022, StringComparison.Ordinal) \u0026\u0026 controller.Name.Length \u003E 10\u0060 appears character-identically in 2 files \u2014 src/Rask.Api.Generators/ApiClientGenerator.cs, src/Rask.Api.Generators/RouteTemplate.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Api.Generators/ApiClientGenerator.cs"},"region":{"startLine":760}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ddfff240b1e1aaa42608e01972a79bbf925c51724b2a5119b78f15cce47ed10"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060metadata.TryGetProperty(\u0022ref\u0022, out var r) \u0026\u0026 r.ValueKind == JsonValueKind.String\u0060 appears character-identically in 2 files \u2014 src/Rask.Testing/TestFileBackend.cs, src/Rask.Wasm/Files/WasmFileBackend.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Testing/TestFileBackend.cs"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"78d8332963b7e9b951b1cb3941d0040ed3fd207148ec658860ec6d17828acd67"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060result.ExitCode == 0 \u0026\u0026 result.StandardOutput.Trim().Equals(\u0022true\u0022, StringComparison.OrdinalIgnoreCase)\u0060 appears character-identically in 2 files \u2014 src/Rask.Cli/Commands/DeployCommand.cs, src/Rask.Cli/Commands/NewCommand.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Commands/DeployCommand.cs"},"region":{"startLine":714}}}],"partialFingerprints":{"codehealthFindingId/v1":"51f62689b171fc3620debbec75675764fd3aea071b56ba64a760c84a55e30a4f"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060root.TryGetProperty(\u0022id\u0022, out var idEl) \u0026\u0026 idEl.ValueKind == JsonValueKind.String\u0060 appears character-identically in 2 files \u2014 src/Rask.Server/RaskEndpointExtensions.cs, src/Rask.Wasm/WasmLiveSession.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1671}}}],"partialFingerprints":{"codehealthFindingId/v1":"12aeadaaed0bb8e5d4e1c9a7a1bd80b91eb5dfd3c85812cada0079c162d22803"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060root.TryGetProperty(\u0022path\u0022, out var p) \u0026\u0026 p.ValueKind == JsonValueKind.String\u0060 appears character-identically in 2 files \u2014 src/Rask.Server/RaskEndpointExtensions.cs, src/Rask.Wasm/WasmLiveSession.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2442}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f0711afcb64cd936391a8e3fde14a7e8a3ea2aa5b54dd0e04f32f4bf324e532"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060root.TryGetProperty(\u0022query\u0022, out var q) \u0026\u0026 q.ValueKind == JsonValueKind.String\u0060 appears character-identically in 2 files \u2014 src/Rask.Server/RaskEndpointExtensions.cs, src/Rask.Wasm/WasmLiveSession.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2450}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a98879dcd869fa3f912a3110da9e1de6ad36a526709b0cb195fd1d945376dd0"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060root.TryGetProperty(\u0022replace\u0022, out var rEl) \u0026\u0026 rEl.ValueKind == JsonValueKind.True\u0060 appears character-identically in 2 files \u2014 src/Rask.Server/RaskEndpointExtensions.cs, src/Rask.Wasm/WasmLiveSession.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2453}}}],"partialFingerprints":{"codehealthFindingId/v1":"979a0c71bfd857d9be4cd3d640bb330b4afc072e13ce67221fd40134d07cbbd5"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060root.TryGetProperty(\u0022type\u0022, out var t) \u0026\u0026 t.ValueKind == JsonValueKind.String\u0060 appears character-identically in 2 files \u2014 src/Rask.Server/RaskEndpointExtensions.cs, src/Rask.Wasm/WasmLiveSession.cs. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1521}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5cecd79dc7255fb674e06f07ae81abe108d8ac582d0e4eada34b1b922b585a3"}},{"ruleId":"X2","level":"note","message":{"text":"Not all async methods take a CancellationToken: Only 372/621 async methods accept a CancellationToken, so in-flight work can\u0027t be stopped early when the caller gives up \u2014 whatever ends it in your host (shutdown signal, timeout, abandoned request, user cancel). Thread a token through the call chain and honour it at each await and loop; where a method genuinely cannot be interrupted, omitting it is a deliberate choice \u2014 judge against your hosting model."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"bf623a92fb752b336427856888a9b386c434e686662a2cdc1bba21832c0a048c"}},{"ruleId":"X28","level":"warning","message":{"text":"Index access outside its own emptiness guard: This condition tests \u0060url\u0060 for emptiness and then indexes it on a branch that test does not reach. \u0060url[0]\u0060 is evaluated whenever the guarded half is false \u2014 which includes the case the guard exists to anticipate, \u0060url\u0060 being empty \u2014 so an empty \u0060url\u0060 indexes position 0 of nothing and throws. This same condition already shows the intended bracketing at line 27: \u0060url[1]\u0060 sits INSIDE the guard. Either the guard is load-bearing, in which case this access escapes it and crashes, or \u0060url\u0060 cannot be empty here, in which case the guard beside it is dead code \u2014 the condition is wrong under both readings. Move the parenthesis so the emptiness test brackets every access to \u0060url\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Routing/LocalUrl.cs"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"da9acf5e2a938753164aa54bb43e20dd65a720929430108943560c4233ae26b0"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch (Exception)\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Blazor/BlazorComponent.cs"},"region":{"startLine":432}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e8f431e261028ce5a36949cb9f860f51114b295f9a852d6f325e532c0fc58ed"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/ModelGraphWalker.cs"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"1eb26ef97a26adca7a0fb8fda1b93e850f76433e50f4ff362c17366f1dc48679"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Forms/ModelGraphWalker.cs"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"60e24b0c939411b4188a6420426cd2400c2c7ca6deeae58e5ec12115dff1a5b9"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskDrainService.cs"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"b70c728ad895ad51c833719f401b9da3e3a03e949f2b5889b7b7187839b0c470"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1364}}}],"partialFingerprints":{"codehealthFindingId/v1":"e37ac9c04cdf902c1619c9e33a22f5cce3f59526ac4220228ee1199e837edc24"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1443}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b08b28955296f605ea52a54fcf508e11edfb93556b79efe6fdaf47467e3c4f9"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":1600}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1cba1fcc481568423e84107d5f68697762923ffd8335351ce492a98626e5171"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Server/RaskEndpointExtensions.cs"},"region":{"startLine":2218}}}],"partialFingerprints":{"codehealthFindingId/v1":"13feff3873925d29520298f80cfbdc9d0d895e7b652969b64e6df26e2e4c005f"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm.Tasks/BakeScopedAssetsTask.cs"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"f620f7408a0693f38d67d4ef54631aca2a7cfaf23dc2f13190ba0ddcc52cfa8b"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (caught, then discarded): \u0060catch\u0060 takes every exception and records none of it \u2014 the body neither logs it, rethrows it, nor even names it, so the failure is discarded as completely as by an empty catch and only the substituted value survives. Log it through whatever this codebase already uses to report problems, narrow the catch to the exception this call can actually raise, or say in a comment on the catch why the failure genuinely cannot matter."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Wasm/RouteSeeder.cs"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"a74d5bf359c6271c9af8b7896a00d2b6c3a0c91b7b9da353ace7959244246479"}},{"ruleId":"X6","level":"note","message":{"text":"Hand-rolled JSON/XML parsing via regex: A regex whose pattern encodes JSON/XML syntax is parsing a structured format by hand \u2014 malformed or differently-typed content (e.g. \u0060\u0022amount\u0022: \u00225\u0022\u0060 as a string) silently mis-parses instead of failing validation. This project already references a real parser; use it here too."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/DevTarget.cs"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0fe6bb365002920fd1e5452e100c1ed1ed2632dc08467ca297960b1a385244b"}},{"ruleId":"X6","level":"note","message":{"text":"Hand-rolled JSON/XML parsing via regex: A regex whose pattern encodes JSON/XML syntax is parsing a structured format by hand \u2014 malformed or differently-typed content (e.g. \u0060\u0022amount\u0022: \u00225\u0022\u0060 as a string) silently mis-parses instead of failing validation. This project already references a real parser; use it here too."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/DevTarget.cs"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c47c5d52dc79d982ee1eaf4e3a8499ff24662bbc0735b37015b183110a70dfb"}},{"ruleId":"X6","level":"note","message":{"text":"Hand-rolled JSON/XML parsing via regex: A regex whose pattern encodes JSON/XML syntax is parsing a structured format by hand \u2014 malformed or differently-typed content (e.g. \u0060\u0022amount\u0022: \u00225\u0022\u0060 as a string) silently mis-parses instead of failing validation. This project already references a real parser; use it here too."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/DevTarget.cs"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffb8f9181c4b0176d34371b4963901263b549ef65932e7538b73311ccb17b50b"}},{"ruleId":"X6","level":"note","message":{"text":"Hand-rolled JSON/XML parsing via regex: A regex whose pattern encodes JSON/XML syntax is parsing a structured format by hand \u2014 malformed or differently-typed content (e.g. \u0060\u0022amount\u0022: \u00225\u0022\u0060 as a string) silently mis-parses instead of failing validation. This project already references a real parser; use it here too."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/DevTarget.cs"},"region":{"startLine":276}}}],"partialFingerprints":{"codehealthFindingId/v1":"01d459ddb3e265eca643d42a7d4588808d21e4a3594b3e4cff3055bcec70f23e"}},{"ruleId":"X6","level":"note","message":{"text":"Hand-rolled JSON/XML parsing via regex: A regex whose pattern encodes JSON/XML syntax is parsing a structured format by hand \u2014 malformed or differently-typed content (e.g. \u0060\u0022amount\u0022: \u00225\u0022\u0060 as a string) silently mis-parses instead of failing validation. This project already references a real parser; use it here too."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/DevTarget.cs"},"region":{"startLine":286}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b3b613aaa22b59e8caf813e470bd3ffbd26ab668de4a55503826f7dd7c3b3fe"}},{"ruleId":"X6","level":"note","message":{"text":"Hand-rolled JSON/XML parsing via regex: A regex whose pattern encodes JSON/XML syntax is parsing a structured format by hand \u2014 malformed or differently-typed content (e.g. \u0060\u0022amount\u0022: \u00225\u0022\u0060 as a string) silently mis-parses instead of failing validation. This project already references a real parser; use it here too."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Cli/Scaffolding/ProjectContext.cs"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"068fa1be9e0b6dcd1e6cd34edb7a7beed139d2eed73f413446f8fd5befa2e35d"}},{"ruleId":"X6","level":"note","message":{"text":"Hand-rolled JSON/XML parsing via regex: A regex whose pattern encodes JSON/XML syntax is parsing a structured format by hand \u2014 malformed or differently-typed content (e.g. \u0060\u0022amount\u0022: \u00225\u0022\u0060 as a string) silently mis-parses instead of failing validation. This project already references a real parser; use it here too."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Site/Shared/Markdown.cs"},"region":{"startLine":341}}}],"partialFingerprints":{"codehealthFindingId/v1":"d93595cb03b55350e6e55905264d8742bffbd9c2f5cd63e6455ade455a636595"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060BcryptCost\u0060 falls back to \u00600\u0060 when \u0060int.TryParse(encoded.AsSpan(4, 2), NumberStyles.None, CultureInfo.InvariantCultu\u2026\u0060 is false, with no log or throw \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer to the test rather than a stand-in for a value that could not be read, this is not a silent default: say so in a comment on the member and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Auth.Api/PasswordHasher.cs"},"region":{"startLine":278}}}],"partialFingerprints":{"codehealthFindingId/v1":"80866869a7d1efd513ca2a965d298283a90f5d439ab5b29e066256d34804ae06"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060LineOf\u0060 falls back to \u00600\u0060 when \u0060int.TryParse(item.GetMetadata(\u0022ModuleLine\u0022), out var line)\u0060 is false, with no log or throw \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer to the test rather than a stand-in for a value that could not be read, this is not a silent default: say so in a comment on the member and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.External.Tasks/WriteExternalPropsRequestTask.cs"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"570df625b0aecefe0442f640b773b6c904d40baab3042a78af640ce5bc325636"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060Bit\u0060 falls back to \u0060-1\u0060 when \u0060bits.TryGetValue(name, out var bit)\u0060 is false, with no log or throw \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer to the test rather than a stand-in for a value that could not be read, this is not a silent default: say so in a comment on the member and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Generators/ComponentFactoryGenerator.cs"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"139acac41f6a3339a1d23e2116b490d7c3b38f33402e262fe58e2377b7e83479"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskBadge.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskBadge.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IBadge.cs"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"55496b77eb5e42e805d4df33ab09268654dfa220f7411596db60b29bf5d92a53"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskBattery.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskBattery.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IBattery.cs"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"74c3319475a5b5e9685eead148be82c7aa770478ea16dd491251425974c280f6"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskBattery.getStatus\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskBattery.getStatus\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IBattery.cs"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8be4191a6a36822b2bfcea502b9c13e71b08c8e3cfced21a213ecf6a520048a"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskApi.cookieGet\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskApi.cookieGet\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/ICookies.cs"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2a87391aaff22bc7c0e011626c48d1b96ab43b94d19ffa1592784f169a9257c"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskApi.cookieSet\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskApi.cookieSet\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/ICookies.cs"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"75ab747b6b5afb49e4e5f0bf8221129d626e7899a6ddd9c435d2c53cb655f3bf"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskApi.cookieDelete\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskApi.cookieDelete\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/ICookies.cs"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"875b24a56fa740ba1a246f319e66ec2f4307fa81af3de35e28370cc785308da2"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskApi.cookieAll\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskApi.cookieAll\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/ICookies.cs"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"25c9336a9c97287adab77dae86317611c4f68084d9ad6b61b87a14bd35ea43f9"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskCrypto.randomUuid\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskCrypto.randomUuid\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/ICrypto.cs"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"42a728d895c8b757958c492ac058d07b318415940be0adcdce73255604372c77"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskCrypto.randomBytes\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskCrypto.randomBytes\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/ICrypto.cs"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"839522d305b135a0da560f268dd4957fb1770f034a81f57c82a60b04941eee28"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskCrypto.digestHex\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskCrypto.digestHex\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/ICrypto.cs"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"608d2e0172468da2dda69763c9643f3b73b250e5a8ebf52e6c00933d06c175e9"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskDeviceMotion.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskDeviceMotion.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IDeviceMotion.cs"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f930418cbb939d24a53a16e7c6fee0526f214306dd85bde413ce4124f125d9e"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskDeviceMotion.requestPermission\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskDeviceMotion.requestPermission\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IDeviceMotion.cs"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"504f5c3c281dc91324945583c2b3a670e528737fac9870516b0a6ca07460f3a5"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskDeviceOrientation.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskDeviceOrientation.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IDeviceOrientation.cs"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4235d720c0287c35482330b89573b74dfc7bcddc88075d127f02b6470eef5f3"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskDeviceOrientation.requestPermission\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskDeviceOrientation.requestPermission\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IDeviceOrientation.cs"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"a645ef6ed9507b2a702f9afae3cac06d7edd8488286598d81de0ace323f821b5"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf3ff744773f6d71cf5c4b8463c431260b50820abba7c9e3c00b6536ab49cc6"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.openFile\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.openFile\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4cd15b5cb30fd01ee46dc7c119523c35ea07ccd98c034c581e84a0dd72bb7e5"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.openFiles\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.openFiles\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9a7228a64c296fafdf73b8ef0549e03d2a2485acbb9678a8f52081a5e7d4958"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.saveFile\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.saveFile\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cfb2e770fd9fb0867ffba5b87dba5502d5c70794a176b01dd096a39dcb6eada"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.openDirectory\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.openDirectory\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0f92d29bbcabda6fa5333d78d77cad400143e882becfc8ce469bcac52cbf5e0"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.readText\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.readText\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b1be305f9b1ef98fb445b00349f522434e3e4fdf8c5097ff9e6bd168ce26ee4"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.readBytes\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.readBytes\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7a58ecb9f6d27ad02f5457390e967d3fcddfe90c2ae5c7b62da5e80042f9179"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.writeText\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.writeText\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"287af928b4d300c60209b2bbb646a68c2d717155dce4cf2ee9aba5cffd44992f"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.writeBytes\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.writeBytes\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"71bfc8afc6ed35cee6764841fc671744ba0e935049e7864874bf45df0cfc0b69"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.release\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.release\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"d713e545eb00106d75524808f2f1be7494194edec6cc78a68f0f699bb04497b3"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.getFile\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.getFile\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"c06afa631e8005589bd1430a7a32de87422ff41e05dae79f36283f38ab84408b"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskFs.release\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskFs.release\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IFileSystemAccess.cs"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"07fc1bb92721e4ba7d55128b5bf0bb6e0b377e9b879840417ad0bb85bfb7b159"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskGamepad.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskGamepad.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IGamepad.cs"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f9fe6b55699731e4e7ee8cd86f5f0c9bdc809026f4e23a85ab4f378e5ad3ea8"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskGamepad.unwatch\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskGamepad.unwatch\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IGamepad.cs"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae92034545ee3c976a4d2827eb4a064f2dd2c1d6687cd3118c77220ad42d7f02"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskApi.geolocation\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskApi.geolocation\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IGeolocation.cs"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e3c2e95ba4242850f847b5cfd5dc4814f6feee06f2ffe6003dc42085b577e0e"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskIdb.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskIdb.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IIndexedDb.cs"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b85e5cc317009ab8eec38471291f43661c76bf3574045a078f599bcf4078617"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskIdb.setBytes\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskIdb.setBytes\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IIndexedDb.cs"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"55c8f7ec06e26a8ba2b8450ea31dc9793581b4e846fc4a8ff07f577694f20b10"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskIdb.getBytes\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskIdb.getBytes\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IIndexedDb.cs"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d7ee5e43162c7c2ab263a6e8b704d8bfd9e0ce2b5313af514e94bc42cac8e38"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskIntersect.unobserve\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskIntersect.unobserve\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IIntersectionObserver.cs"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c278104c2e7f01f2c93f4de7787e34b66261e1230413cbb73d9562d1716c666"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskApi.matchMedia\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskApi.matchMedia\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IMediaQuery.cs"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ba437cde5861017ded41bf2252a5fba185122dca1a0a9220828430815c1cf36"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskMediaSession.isSupported\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskMediaSession.isSupported\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IMediaSession.cs"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"44d4349f542f1e89467652cd1e182b5b2aa2e09302758832d17abfa6bafe20a7"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskMediaSession.setMetadata\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskMediaSession.setMetadata\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IMediaSession.cs"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2617a529b1c518c5008fa92acc74f86762f7239ae73cc0b4bca40f1469735e8"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskMediaSession.setPlaybackState\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskMediaSession.setPlaybackState\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IMediaSession.cs"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb19872ac06041d1449c35299e4d8b1e2bb8e638abe898d3154bd86949993012"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskMediaSession.setActionHandler\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskMediaSession.setActionHandler\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IMediaSession.cs"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"72f77bb0050d2b5eafe70dc7b4497f1793ccbb9b62443db9dd0bf97aa5af8468"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskMediaSession.removeActionHandler\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskMediaSession.removeActionHandler\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IMediaSession.cs"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"0af2c431ca199fe3187937bd2a545ba335370ec5ebef179416450410fdeb3964"}},{"ruleId":"X8","level":"warning","message":{"text":"Unresolved JS interop binding: \u0060__raskMutation.unobserve\u0060 is invoked from C# here, and no definition of that name was found by the search this dimension ran: 23 first-party JavaScript file(s) (.js/.mjs/.cjs, vendored trees excluded) plus 23 markup file(s) scanned for inline \u003Cscript\u003E blocks (.html/.cshtml/.razor). NOT searched: scripts fetched or injected at runtime, and vendored/dynamically-loaded bundles \u2014 a definition living in one of those is invisible here. To settle it, grep the repository for \u0060__raskMutation.unobserve\u0060. If it is defined nowhere, this call throws or silently no-ops at runtime, and a swallowed interop catch will hide it \u2014 define it, or invoke a wrapper that exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.Core/Browser/IMutationObserver.cs"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"b83a2dcb94710e8afb1903daec1cf3592aad6e0c3a449664e992984d7c6d964a"}},{"ruleId":"X9","level":"note","message":{"text":"Subsumed condition operand: \u0060dash \u003E 0\u0060 can never decide this \u0060\u0026\u0026\u0060 \u2014 every value satisfying \u0060dash \u003E= 9\u0060 also satisfies \u0060dash \u003E 0\u0060, so the \u0060\u0026\u0026\u0060 chain is already decided by the former. The expression is equivalent to the chain without it, which means it is narrower than it reads. Delete the dead operand, or narrow the surviving one if IT is the accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"src/Rask.SQLite.Browser/IndexedDbSnapshotStore.cs"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"c22d687302d6a2fbb1a1a40cb275038885ff8aa37547a6cb382c6d0aa54412ab"}}],"taxonomies":[{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d","organization":"MITRE","informationUri":"https://cwe.mitre.org/","isComprehensive":false,"shortDescription":{"text":"The MITRE Common Weakness Enumeration (CWE)."},"taxa":[{"id":"CWE-1032","guid":"5f21e517-68aa-a650-9a25-5771ef024637","name":"OWASP Top Ten \u2014 Security Misconfiguration category","shortDescription":{"text":"OWASP Top Ten \u2014 Security Misconfiguration category"},"helpUri":"https://cwe.mitre.org/data/definitions/1032.html"},{"id":"CWE-1059","guid":"a2381a08-60f6-9554-a8b8-f3018cfaaca5","name":"Insufficient Technical Documentation","shortDescription":{"text":"Insufficient Technical Documentation"},"helpUri":"https://cwe.mitre.org/data/definitions/1059.html"},{"id":"CWE-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-1395","guid":"800e09e7-c11a-8654-9fa6-86f398995fed","name":"Dependency on Vulnerable Third-Party Component","shortDescription":{"text":"Dependency on Vulnerable Third-Party Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1395.html"},{"id":"CWE-16","guid":"659db3ea-affc-8453-8add-c1218fbfcb92","name":"Configuration","shortDescription":{"text":"Configuration"},"helpUri":"https://cwe.mitre.org/data/definitions/16.html"},{"id":"CWE-214","guid":"b10ad120-fb22-1351-9348-aa23b453e815","name":"CWE-214","shortDescription":{"text":"CWE-214"},"helpUri":"https://cwe.mitre.org/data/definitions/214.html"},{"id":"CWE-22","guid":"b68d9ca7-bdde-d057-a6cc-9f8b1e739552","name":"CWE-22","shortDescription":{"text":"CWE-22"},"helpUri":"https://cwe.mitre.org/data/definitions/22.html"},{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-345","guid":"d80d4b65-bbbe-b65d-958e-7ac466af18f9","name":"CWE-345","shortDescription":{"text":"CWE-345"},"helpUri":"https://cwe.mitre.org/data/definitions/345.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"CWE-353","shortDescription":{"text":"CWE-353"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-506","guid":"401d6455-56e3-0552-9a39-f77461673e3f","name":"CWE-506","shortDescription":{"text":"CWE-506"},"helpUri":"https://cwe.mitre.org/data/definitions/506.html"},{"id":"CWE-522","guid":"71fb233e-ce6a-ae57-9419-ef8373540b09","name":"CWE-522","shortDescription":{"text":"CWE-522"},"helpUri":"https://cwe.mitre.org/data/definitions/522.html"},{"id":"CWE-532","guid":"1cd8877a-76e8-ce54-b40b-779af23364a0","name":"CWE-532","shortDescription":{"text":"CWE-532"},"helpUri":"https://cwe.mitre.org/data/definitions/532.html"},{"id":"CWE-552","guid":"3492436b-eca2-9c54-9ba3-5dade427c903","name":"CWE-552","shortDescription":{"text":"CWE-552"},"helpUri":"https://cwe.mitre.org/data/definitions/552.html"},{"id":"CWE-732","guid":"1da27e8f-b330-7650-ab63-bd61953eae5d","name":"Incorrect Permission Assignment for Critical Resource","shortDescription":{"text":"Incorrect Permission Assignment for Critical Resource"},"helpUri":"https://cwe.mitre.org/data/definitions/732.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Command Injection","shortDescription":{"text":"Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"OS Command Injection","shortDescription":{"text":"OS Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Cross-site Scripting (XSS)","shortDescription":{"text":"Cross-site Scripting (XSS)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-829","guid":"13c33925-97fb-5a5e-b40c-56d328b8a4d7","name":"CWE-829","shortDescription":{"text":"CWE-829"},"helpUri":"https://cwe.mitre.org/data/definitions/829.html"},{"id":"CWE-88","guid":"32dec161-013d-ac58-8599-1309e12e67f5","name":"CWE-88","shortDescription":{"text":"CWE-88"},"helpUri":"https://cwe.mitre.org/data/definitions/88.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"SQL Injection","shortDescription":{"text":"SQL Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-937","guid":"16f316ae-415c-b354-a59b-1f7905f756e9","name":"Using Components with Known Vulnerabilities","shortDescription":{"text":"Using Components with Known Vulnerabilities"},"helpUri":"https://cwe.mitre.org/data/definitions/937.html"},{"id":"CWE-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Code Injection","shortDescription":{"text":"Code Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":155,"secretScannerRunsExcluded":0}},"redactionTokens":["A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."]}]}