Commit c04219b
fix(test): full de-flake sweep — parallel-starvation deadline-polls → deterministic joins (#1319)
* test(network/signin): de-flake state-machine deadline-polls by joining the actual work
Four tests waited for fire-and-forget async work via a fixed wall-clock
deadline (asyncAfter probes / Task.sleep settle windows) and starved under
CI parallel oversubscription — the deadline elapses before the awaited work
lands and the test times out even though the work DID complete. Replaced each
poll with a deterministic JOIN of the real work; assertions unchanged.
- TPPSignInBusinessLogicStateMachineTests.testLogIn_racingAuthDocLoad_firesRequestOnceReady:
dropped the 0.5s/1.5s asyncAfter probes; wake the instant the mock records
the credential request via a new join seam.
- UnifiedOPDSServiceStateMachineTests.testFetchLoansFeed_blocksUntilLoaded_thenFetches
& OPDSFeedServiceStateMachineTests (same name): dropped the 80ms settle sleep
and joined the held fetch Task with `await fetchTask.value`. Mid-flight
negatives hold without a settle — the awaitReady gate can't fire HTTP or
complete while state is .detailsLoading.
- NotificationServiceStateMachineTests.testHoldNotification_blocksUntilLoaded_thenNavigates:
dropped the 30ms subscribe-settle sleep; the state stream is a
CurrentValueSubject so a late subscriber replays the terminal state — no
lost-wakeup race, `await outcomeTask` is the join.
Added a test-only `onExecuteRequest` join seam to TPPRequestExecutorMock
(fires synchronously as executeRequest records a URL; cleared in reset()).
**Scope:** test-only. Zero production LOC changed — all edits under
PalaceTests/. The sign-in test is money-path but its production path
(logIn/awaitReadyThenRetryLogIn) is untouched; only the mock and the test's
wait mechanism changed, and the prod-behavior assertions (request fires,
carries /patrons/me) are preserved.
**Not done:** did not touch SignInWebSheetIntegrationTests (real WKWebView
cold-start, already documented FLAKE-003-OK — env-bound, not a deadline poll).
**Deferred:** none.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(catalog): de-flake parallel-starvation deadline polls via work-unit joins
CI runs PalaceTests with sim-clone oversubscription; tests that waited on a
fire-and-forget async op (Task.detached refresh, load()'s currentLoadTask) via
a fixed wall-clock deadline (awaitCondition / fulfillment(timeout:) / Task.sleep
poll) starved past the 120s executionTimeAllowance. Fix: join the actual work
unit instead of polling a deadline.
CatalogCacheKeyAndIsolationTests:
- testConcurrentStaleReads_AcrossDistinctURLs_EachURLGetsItsOwnRefresh — join
all 3 concurrent .utility refreshes via _awaitAllBackgroundRefreshesForTesting
- testConcurrentStaleReads_BackgroundRefreshDoesNotPoisonNeighborKey — join the
single refresh via _awaitBackgroundRefreshForTesting
- testInMemoryCache_AfterSystemMemoryWarning_... + testMemoryWarning_ClearsBoth
— handler evicts synchronously under NotificationCenter.post; assert directly
- removed the now-orphaned awaitCondition wall-clock poll helper
CatalogDomainTests: dropped two stale "give cache queue time" Task.sleep(100ms)
waits — invalidateCache is a synchronous lock mutation (no queue since the SWR
refactor).
CatalogViewModelTests: 8 sites (load error/nil/offline, forceRefresh, SWR A→B→A
waitUntilLoaded) now join currentLoadTask via _awaitLoadForTesting. Reconnect
auto-reload left as a bounded observable-effect poll (documented un-joinable:
the reload hops through two untracked bare Tasks off the reachability
publisher).
SideloadedLaneTests: awaitLoaded/awaitFailure join currentLoadTask instead of a
20s $state fulfillment.
Production seams (additive, behavior-identical, gated/defaulted — prod path
unchanged):
- CatalogRepository._trackRefreshTasksForTesting() +
_awaitAllBackgroundRefreshesForTesting() (refreshTracking flag defaults off;
prod never appends/grows the tracked-task array)
- CatalogViewModel._awaitLoadForTesting() (reads the already-retained
currentLoadTask handle)
No assertions weakened; no XCTSkip, no raised executionTimeAllowance, no disabled
parallelism. Both production files pass `swiftc -parse`.
**Scope:** test-only de-flake batch (CATALOG). Prod change is 2 files / 66 LOC,
all additive underscore-prefixed test seams + doc comments — zero runtime
behavior change on any production path (new tracking is opt-in and defaults off;
the load seam only reads an existing handle). No money-path (borrow/DRM/sign-in)
code touched. Not done: the reconnect-auto-reload connectivity-publisher hop
still lacks a retained-handle join seam (deferred to the connectivity owner);
its test keeps a bounded observable-effect poll.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(deflake): join fire-and-forget async work instead of polling wall-clock deadlines (ACCOUNTS/PLATFORM batch)
De-flakes fixed-deadline polls that starve under CI sim-clone oversubscription
(2 clones on a small runner) and blow the 120s executionTimeAllowance. Every
change replaces a wall-clock deadline (Task.sleep-then-assert, RunLoop.run(until:)
spin, tight fulfillment ceiling) with a deterministic JOIN on the actual work.
Test-side conversions:
- AppLaunchTracker{,Extended}Tests: join the fire-and-forget catalogLoaded metrics
report via new tracker.awaitPendingMetricsReport() seam (was: sleep 100/200ms).
- AppHealthViewModelTests: join loadData() via new viewModel.awaitLoadForTesting()
seam (was: 5× sleep 200ms); offline-queue status update now joins the ViewModel's
main-hopped $offlineQueueStatus sink via fulfillment (was: sleep 200ms).
- AccountStateMachineTests.testStateStream_emitsCurrentThenTransitions: subscription
barrier on the stream's first (CurrentValueSubject current-value) emission before
driving transitions (was: 2× sleep 30ms; genuine intermediate-state ordering hazard).
- AppContainerResetTests: join presenter $hasActiveSession @published emission (was:
2s RunLoop.main.run(until:) spin).
- AccountDetailViewModelTests: settle() joins $isLoadingAuth reaching false (was:
yield×3 + sleep 50ms).
- ViewModelComputedPropertyTests: drainMainQueueAsync() for the other-book no-react
case (was: sleep 200ms).
- ActiveSessionsViewModelTests: widen 3 genuine-join fulfillment ceilings 0.5s->5.0s
to match the already-fixed site 185 precedent (join mechanism unchanged; only the
failure-bound widened so a real join can't starve under oversubscription).
Production seams (test-only join points, behavior-identical in production):
- AppLaunchTracker: retain the metrics-report Task in metricsReportTask + expose
awaitPendingMetricsReport(). Same task still runs detached; we only keep its handle.
- AppHealthViewModel: retain the loadData() Task in loadTask + expose
awaitLoadForTesting(). Same task still runs; we only keep its handle.
No assertions weakened; no XCTSkip; no disabled parallelism. Left as-is (correctly):
callback-fulfilled expectations, condition-driven bounded spins (UserAccountPublisher
deinit-cancel loop, AccountsManagerCancellation suspend-point spin), negative-assertion
settle windows (AccountsManagerFirstRunDecode 0.5s no-second-decode; bounded, not a
120s risk), and awaitReady() slow-path tests (CurrentValueSubject replay makes
resolution ordering-independent). RemoteFeatureFlags 10s sleep is a withTimeout
cancellation probe, not a deadline poll.
**Scope:** 7 target test dirs (Accounts/Platform/Crawl/ViewModels/Migrations/
ImageLoading/AppInfrastructure). Crawl + Migrations had no deadline-polls. Skip-list
files (OfflineQueueService/PositionSync/Accessibility/PerformanceMonitor/
StateMachineWiring/AccountDetailsURL/PoolResponsivenessProbe) untouched.
**Not done:** no build/verify run (CI verifies per batch brief); no push/merge.
**Deferred:** none. No money/critical-path production behavior changed — the two
prod seams only retain an existing Task handle for a test join.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(reader): join fire-and-forget async instead of polling wall-clock deadlines (de-flake)
De-flakes parallel-starvation deadline-poll tests in the reader/PDF/bookmark
areas. Under CI's 2-sim-clone oversubscription, tests that waited a FIXED
wall-clock interval (Task.sleep / debounce-deadline poll) for a fire-and-forget
async op could starve past the deadline and hit the 120s executionTimeAllowance.
Fix: JOIN the actual work via retained-Task seams / a persist-completion signal
instead of racing a deadline. Also fixes one shared-state root (mock defaulting
to the production singleton registry).
Prod seams added (all behavior-identical; nil/uncalled in production):
- TPPLastReadPositionPoster: retain spawned server-post Tasks + awaitPendingWrites()
- TPPReaderTOCBusinessLogic: retain the init TOC-load Task + awaitTOCLoad()
- TypographyService: onDidPersistForTesting callback fired after each debounced persist
Shared-state root fixed:
- MockPDFDocumentMetadata now injects an isolated TPPBookRegistryMock per instance
instead of letting the parent init default to AppContainer.production().bookRegistry
(every mock was touching the shared singleton — cross-test pollution). Behavior
the tests assert (bookmark-set membership) is unchanged.
Tests converted from deadline-polls to deterministic joins:
- TPPLastReadPositionPosterTests (5 Task.sleep -> awaitPendingWrites)
- TPPReaderTOCBusinessLogicTests (4 XCTNSPredicate 10s polls -> awaitTOCLoad)
- TypographyServiceTests.testSettingsPersistedAfterDebounce (predicate poll -> persist-signal join)
No assertions weakened; no XCTSkip/raised allowances/loosened asserts.
**Scope:** Reader2/PDF/Bookmark de-flake only. Left genuine event-driven waits
untouched (spy-navigator/completion-fulfilled expectations, count-matched
concurrency joins, main-actor-drain barriers) — those already join real work.
**Not done:** TypographyServiceIntegrationTests.swift is present in the project
group but NOT compiled (no PBXSourcesBuildPhase entry; references a
TypographyPersistence protocol that does not exist in prod) — its debounce
Task.sleep polls are inert (never run in CI), so left as-is.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(audiobooks): de-flake parallel-starvation deadline-poll waits (swarm AUDIOBOOK)
CI runs PalaceTests with 2 sim clones on a small runner; tests that wait for
a fire-and-forget async op via a FIXED WALL-CLOCK deadline starve under
oversubscription and hit the 120s executionTimeAllowance. This converts those
waits to deterministic JOINS of the actual work unit.
Fixed:
- AudiobookBookmarkBusinessLogic{,PositionWrite}Tests: position-write detached
Task now joined via a new `_awaitPositionWriteForTesting()` seam (retained
Task-handle) instead of `wait(for:timeout:)` on the completion.
- NowPlayingCoordinator{,Background}Tests: debounced `Task.sleep` update now
joined via a new `_awaitPendingUpdateForTesting()` seam instead of
`awaitCondition(timeout:5)` polling MPNowPlayingInfoCenter.
- AudiobookSessionPresenterTests: replaced the fixed-50ms
`RunLoop.main.run(until:)` publisher-delivery spin with the deterministic
FIFO `drainMainQueue()` (16 sites via the shared helper).
- AudiobookDataManagerSyncTests: mock POST completions moved off
`.global().asyncAfter` onto a serial completion queue + `drainCompletions()`
barrier; predicate-poll expectations replaced with `syncQueue.sync {}` +
`drainCompletions()` joins.
Production seams added are underscore-prefixed, test-only, and behavior-
identical (no production call path invokes them; the write Task runs exactly
as before, only its handle is now retained).
Left as-is (genuine event-joins / un-joinable, noted): AudiobookLoader{,Dispatch,
OPDSShapeMatrix}Tests + vendor adapter tests (real AppContainer.production()
pipeline / @MainActor-Task hops driven by runloop spin, no clean seam without
a DRM-path refactor); AudiobookOpenStateRace / FirstOpenHang (event-firing
gate waits); AudioEngineWrapper / LoaderFinalizeBuild (synchronous completions);
the debounce-dealloc crash-survival test (no work unit to await by design).
**Scope:** test-only de-flake + two underscore-prefixed test-join seams on
AudiobookBookmarkBusinessLogic + NowPlayingCoordinator. No behavior change.
**Not done:** vendor-adapter (LCP/Bearer/OpenAccess) and AudiobookLoader Task
joins — those hit the real fulfillment/DRM pipeline and warrant a swarm, not a
lone seam; left with inline reasoning.
**Deferred:** none.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(mybooks): de-flake return/auth/fulfillment deadline-poll waits (join, don't poll)
Convert wall-clock deadline-polls on fire-and-forget async to deterministic
joins across the return / auth / download-fulfillment money-path tests. Under
CI oversubscription (2 sim clones, small runner) these polls
(awaitConditionAsync / Task.sleep loops / asyncAfter+wait / while-Date loops)
starve and hit the 120s executionTimeAllowance.
Join patterns used:
- Retained-Task join: await inFlightTasksSnapshotForTesting() Task.value
(BookReturnService + DownloadAuthRetryHandler both retain their fire-and-
forget Tasks; the auto-removal is the tail of each tracked body, so
await task.value joins body+cleanup deterministically).
- Synchronous retention insert -> direct assert (returnBook / handleAuth insert
the tracked Task synchronously before returning; count is deterministically
>=1 with no poll).
- Prompt-firing expectation: fulfil an XCTestExpectation from the effect edge
(error-publisher sink, reauthenticator.onAuthenticate, delegate.onStartDownload)
instead of polling a captured-array count behind a fixed asyncAfter delay.
- Main-actor barrier flush (await Task { @mainactor }.value) for all-@mainactor
chains and absence-assertions, replacing fixed settle sleeps.
Prod seam added (test-only behavior, behavior-identical):
- DownloadAuthRetryHandler.inFlightTasksSnapshotForTesting() — a @mainactor
read-only copy of the existing inFlightTasks set, mirroring the established
BookReturnService seam. Mutates nothing; no production path changes.
Un-joinable sites left with an inline note + kept as loud-on-timeout waits (no
retention handle available without a larger prod change):
- BookSignInRedirectHandler SAML-cookies-expired retry (background Task { }).
- LCPFulfillmentHandler stored-fulfillment-task (untracked Task in a void method).
- BookReturnService deinit observation (ARC last-release, not awaitable).
- TokenRefreshInterceptor coordinator paths — barrier-flush (no retention seam
on the interceptor yet; flagged as the complete follow-up).
No assertions weakened; no XCTSkip; no raised allowances; parallelism untouched.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(mybooks): de-flake download/borrow/registry deadline-poll waits (join, don't poll)
Convert fixed-wall-clock deadline polls (awaitCondition / awaitConditionAsync /
Task.sleep loops / RunLoop.run(until:)) that waited on fire-and-forget async
work into deterministic joins. Under CI oversubscription (2 sim clones) those
polls starve and blow the 120s executionTimeAllowance; joining the actual work
removes the wall-clock race entirely.
Test-side: await the SUT's own async entry points / retained-Task seams,
drain-then-assert for synchronous registry+notification effects, and use
prompt-firing NotificationCenter expectations (fulfilled by the SUT's own
post) in place of RunLoop deadline polls. Publisher joins via a shared
awaitPublished/awaitPublishedAsync helper.
Prod: add behavior-identical join seams only — fire-and-forget `Task {}` bodies
extracted verbatim into `...Async()` siblings whose sync wrapper is
`Task { await ...Async() }` (enqueuePendingAsync, startBorrowAsync,
limitActiveDownloadsAsync, pauseAllDownloadsAsync, processAsync), plus
retained-Task `private(set) var last...Task` handles for tests to await. Same
calls, same order, same side effects; no logic, branch, or state-transition
change. Mirrors the existing schedulePendingStartsIfPossible→Async split.
No assertions weakened, no XCTSkip, no raised allowance, parallelism untouched.
**Scope:** de-flake pass over PalaceTests/MyBooks, PalaceTests/Book,
PalaceTests/BookStateManagement (return/auth/fulfillment slice committed
separately in the preceding commit). Prod seams are money-path
(borrow/download) and confirmed test-only-behavior (behavior-identical joins).
**Deferred:** a full retention seam for TokenRefreshInterceptor's ~20
fire-and-forget Task sites (too broad for a de-flake pass; two interceptor
poll sites left with UNJOINABLE notes). Genuinely un-joinable sites (real
debounce timers, ARC-deinit observation, absence-of-effect settles, SAML
retry background Tasks with no handle) left in place with inline UNJOINABLE
notes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(deflake): add #1315's SignOut/MultiLibrary joins the swarm skipped
The full-sweep swarm branched off develop (which lacked #1315), so its Network
batch skipped TPPSignInBusinessLogicSignOutTests + MultiLibraryTokenIsolationTests
believing they were already on develop. They were only in #1315. Bring those two
join fixes + the TPPDRMAuthorizingMock._awaitDeauthorizeCalledForTesting seam they
need, so the sweep supersedes #1315 completely (BorrowOperationContractTests kept
from the mybooks batch, which fixed the whole Borrow slice).
**Scope:** test-only (2 test files + 1 test mock); no production change here.
* fix(deflake): sync poster join seam (avoid Swift 6 sending self.poster)
The reader batch's `awaitPendingWrites() async` seam, called on the @mainactor
test's non-Sendable poster, tripped Swift 6 'sending self.poster'. Reshaped to a
synchronous `pendingWriteTasksForTesting() -> [Task]` snapshot (a sync call sends
nothing; Task is Sendable) and the test awaits the returned handles. Behavior
identical; consolidated sweep now builds clean.
**Scope:** compile fix for the consolidated de-flake sweep; no behavior change.
* revert(deflake): restore DownloadAuthRetryHandler de-flake to develop (broke behavior)
The mybooks batch's join conversion of DownloadAuthRetryHandlerTests asserted
before the alert-publish/retry-download effect landed → 2 deterministic failures
(testAutoBorrowCompletion_whenBorrowFails, testHandle_401_withoutCredentials).
This class's async structure was flagged partial/complex; reverting its de-flake
(+ the prod seam) to develop's correct version is safer than shipping a broken
money-path join. The class may still occasionally flake under parallel load
(pre-existing) — that's a separate, non-regressing follow-up.
**Scope:** revert 3 files to develop; rest of the sweep unchanged.
---------
Co-authored-by: t <t@t.io>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 0b60497 commit c04219b
76 files changed
Lines changed: 1629 additions & 1044 deletions
File tree
- PalaceTests
- Accounts
- AppInfrastructure
- Audiobooks
- Audiobook
- BookStateManagement
- Book
- CatalogDomain
- CatalogUI
- Mocks
- MyBooks
- Network
- Notifications
- OPDS2
- Platform
- Reader2
- Typography
- SignInLogic
- ViewModels
- Palace
- Audiobooks
- CatalogUI/ViewModels
- MyBooks
- Packages/PalaceCatalog/Sources/PalaceCatalog
- Platform
- Reader2
- Bookmarks
- BusinessLogic
- Typography
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
359 | 359 | | |
360 | 360 | | |
361 | 361 | | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
362 | 373 | | |
363 | 374 | | |
364 | 375 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
125 | 143 | | |
126 | 144 | | |
127 | 145 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
122 | 122 | | |
123 | 123 | | |
124 | 124 | | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
125 | 151 | | |
126 | 152 | | |
127 | 153 | | |
| |||
132 | 158 | | |
133 | 159 | | |
134 | 160 | | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
143 | 164 | | |
144 | 165 | | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
166 | 170 | | |
167 | | - | |
168 | | - | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
169 | 175 | | |
170 | | - | |
171 | | - | |
172 | | - | |
173 | | - | |
| 176 | + | |
| 177 | + | |
174 | 178 | | |
175 | | - | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
176 | 182 | | |
177 | | - | |
| 183 | + | |
| 184 | + | |
178 | 185 | | |
179 | 186 | | |
180 | 187 | | |
| |||
184 | 191 | | |
185 | 192 | | |
186 | 193 | | |
187 | | - | |
| 194 | + | |
188 | 195 | | |
189 | | - | |
190 | | - | |
191 | 196 | | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
200 | 207 | | |
201 | 208 | | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
202 | 217 | | |
203 | 218 | | |
204 | 219 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
58 | 68 | | |
59 | 69 | | |
60 | 70 | | |
| |||
94 | 104 | | |
95 | 105 | | |
96 | 106 | | |
97 | | - | |
| 107 | + | |
98 | 108 | | |
99 | 109 | | |
100 | 110 | | |
| |||
128 | 138 | | |
129 | 139 | | |
130 | 140 | | |
131 | | - | |
| 141 | + | |
132 | 142 | | |
133 | 143 | | |
134 | 144 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
103 | 114 | | |
104 | 115 | | |
105 | 116 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
74 | | - | |
75 | | - | |
76 | | - | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
77 | 83 | | |
78 | 84 | | |
79 | 85 | | |
| |||
193 | 199 | | |
194 | 200 | | |
195 | 201 | | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
202 | | - | |
203 | | - | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
208 | | - | |
209 | | - | |
210 | | - | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
211 | 232 | | |
212 | 233 | | |
213 | | - | |
| 234 | + | |
214 | 235 | | |
215 | | - | |
216 | 236 | | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
217 | 246 | | |
218 | 247 | | |
219 | 248 | | |
| |||
0 commit comments