Commit 5386d45
Adding Bushel Example (#132)
* docs: complete CloudKit schema design and data source research for Bushel demo
Add comprehensive planning documentation for Task 5 (Bushel Version History Tool):
- cloudkit-schema-plan.md: Complete CloudKit schema for RestoreImage, XcodeVersion,
and SwiftVersion record types with fields, indexes, relationships, and implementation phases
- data-sources-api-research.md: API research for xcodereleases.com (JSON API),
swiftversion.net (HTML scraping), and MistKit integration patterns with code examples
- mobileasset-wiki.md: Reference documentation on Apple's MobileAsset framework and MESU server
- firmware-wiki.md: Reference documentation on Apple firmware manifests and version history
Update Task 5 with refined scope focusing on macOS restore images for virtualization,
including data sources (ipsw.me via IPSWDownloads, Mr. Macintosh, MESU XML) and
updated subtasks aligned with implementation phases.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: add public write API and Bushel demo for CloudKit record operations
Add comprehensive public API for creating, updating, and deleting CloudKit records, along with a complete demo application showing real-world usage patterns.
## MistKit Public API Enhancements
### New Public Types
- Add `RecordOperation` struct with factory methods for create/update/delete operations
- Provides clean abstraction over internal OpenAPI-generated types
- Supports all operation types: create, update, forceUpdate, replace, forceReplace, delete, forceDelete
### CloudKitService Write Operations
- Add `modifyRecords(_:)` for batch record operations
- Add convenience methods: `createRecord()`, `updateRecord()`, `deleteRecord()`
- Proper error handling with typed `CloudKitError`
- Batch processing support (handles CloudKit's 200-operation limit)
### RecordFieldConverter Enhancements
- Add `toComponentsFieldValue()` for bidirectional field conversion
- Support all CloudKit field types: string, int64, double, boolean, bytes, date, location, reference, asset, list
- Proper date/timestamp conversion (milliseconds since epoch)
- Nested list support with type preservation
### Sendable Conformance
- Add Sendable to `FieldValue` and nested types (Location, Reference, Asset)
- Add Sendable to `CloudKitService` for concurrency safety
- Enable safe usage in Swift 6 strict concurrency mode
### CustomFieldValue Improvements
- Add memberwise initializer for programmatic construction
- Enable write operations without Decodable dependency
## Bushel Demo Application
Complete CLI tool demonstrating MistKit capabilities for syncing macOS restore images, Xcode versions, and Swift compiler versions to CloudKit.
### Features
- Multi-source data fetching (ipsw.me, xcodereleases.com, swift.org, MESU, Mr. Macintosh)
- CloudKit batch upload with progress reporting
- Record relationships using CloudKit References
- JSON export for offline analysis
- Proper error handling and retry logic
### Architecture
- Clean separation: DataSources → Models → CloudKit → Commands
- Uses ONLY public MistKit APIs (demonstrates proper abstraction)
- Swift 6 strict concurrency throughout
- Sendable-conforming types for thread safety
### Commands
- `sync`: Fetch and upload all data to CloudKit
- `export`: Fetch data and export to JSON (no CloudKit upload)
### Documentation
- Comprehensive README.md with architecture diagrams
- XCODE_SCHEME_SETUP.md for development configuration
- CloudKit schema definitions
- Usage examples and troubleshooting guide
### Dependencies
- IPSWDownloads for ipsw.me API integration
- SwiftSoup for HTML parsing
- ArgumentParser for CLI interface
## Files Changed
### MistKit Core (8 files)
- RecordOperation.swift (new, 122 lines)
- RecordOperation+OpenAPI.swift (new, 63 lines)
- CloudKitService+WriteOperations.swift (new, 151 lines)
- RecordFieldConverter.swift (+131 lines)
- CloudKitResponseProcessor.swift (+42 lines)
- CloudKitService.swift (Sendable conformance)
- FieldValue.swift (Sendable conformance)
- CustomFieldValue.swift (memberwise init)
### Bushel Demo (20 files, 2,437 lines)
- Package.swift and dependencies
- 5 data source fetchers
- 3 model types with CloudKit field mapping
- CloudKit integration layer (service, builder, engine)
- 2 CLI commands (sync, export)
- Comprehensive documentation (README + Xcode setup guide)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update iOS version in MistKit workflow
* feat: add automated CloudKit schema setup with cktool for Bushel demo
Provides declarative schema definition (.ckdb), automated import script, and comprehensive documentation for setting up CloudKit container schema programmatically, enabling easy deployment to development/production environments.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: add TheAppleWiki data source and refactor to Server-to-Server authentication
Major Changes:
1. TheAppleWiki Integration
- Add TheAppleWiki.com as new data source for historical IPSW data
- Create IPSWParser, TheAppleWikiFetcher, and domain models
- Integrate into DataSourcePipeline with parallel fetching
- Add device filtering for VirtualMac variants
- Implement file size parsing and prerelease detection
2. Server-to-Server Authentication Refactoring
- Replace APITokenManager with ServerToServerAuthManager
- Update CLI to accept --key-id and --key-file flags
- Change env vars from CLOUDKIT_API_TOKEN to CLOUDKIT_KEY_ID + CLOUDKIT_KEY_FILE
- Add PEM file validation and helpful error messages
- Update both SyncCommand and ExportCommand
3. CloudKit Schema Fixes
- Add required DEFINE SCHEMA header to schema.ckdb
- Remove system fields (CloudKit adds these automatically)
- Fix setup-cloudkit-schema.sh validation commands
- Update to use 'xcrun cktool get-teams' for token check
- Add --file flag to validate-schema and import-schema commands
4. Documentation & Security
- Add comprehensive IMPLEMENTATION_NOTES.md for future reference
- Create .gitignore with *.pem and .env protection
- Update README with Server-to-Server authentication setup
- Add security best practices for private key management
Files Changed:
- New: TheAppleWiki/ data source directory (IPSWParser, models, fetcher)
- New: IMPLEMENTATION_NOTES.md (session documentation)
- New: .gitignore (private key protection)
- Modified: Authentication throughout (BushelCloudKitService, SyncEngine, commands)
- Modified: Schema and setup script (format fixes, command corrections)
- Modified: README (comprehensive S2S auth documentation)
This refactoring demonstrates production-ready CloudKit integration using
recommended authentication methods and adds historical firmware data coverage.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve data source parsing issues in Bushel sync
Fixed multiple data source fetchers to handle API format changes and
incomplete data, enabling successful sync from all external sources.
Changes:
- MESUFetcher: Switch from XML to PropertyList parsing for Apple MESU
API format change (plist with nested dictionaries)
- TheAppleWikiFetcher: Remove VirtualMac device filter since UniversalMac
restore images work for all Apple Silicon devices
- XcodeReleasesFetcher: Make optional all fields that can be missing in
older Xcode releases (compilers, links, sdks, and nested fields)
- MrMacintoshFetcher: Fix HTML parsing for 3-column table structure and
improve date parsing to handle formats without year
- DataSourcePipeline: Add detailed per-source logging for easier debugging
- schema.ckdb: Add ___recordName QUERYABLE to all record types for
CloudKit query support
All fetchers now handle missing/optional data gracefully and provide
clear error messages when failures occur.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* [skip ci] Adding previous conversation
* docs: add comprehensive CloudKit Server-to-Server authentication guide
Add detailed documentation for setting up CloudKit S2S authentication,
including schema configuration, permissions, and common troubleshooting.
Schema Changes:
- Update all record types (RestoreImage, XcodeVersion, SwiftVersion)
- Grant READ, CREATE, WRITE to both _creator and _icloud roles
- This enables Server-to-Server authentication to create/modify records
Key Findings:
- S2S authentication requires BOTH _creator AND _icloud permissions
- Schema syntax: GRANT READ, CREATE, WRITE TO "role"
- Boolean fields must use INT64 type (0/1)
- Operation type .forceReplace provides idempotency
Documentation includes:
- Complete setup walkthrough from key generation to deployment
- CloudKit permissions model explained for novice developers
- Common errors and solutions (ACCESS_DENIED, schema syntax, etc.)
- Swift implementation examples using MistKit
- Testing and verification procedures
- Production readiness checklist
This resolves the ACCESS_DENIED errors that were blocking CloudKit sync
operations and provides a reusable reference for future projects.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(bushel): add tutorial-quality verbose logging and documentation polish
Enhances the Bushel demo for use in the upcoming blog post and as a reference
implementation for novice developers and Claude Code (Celestra demo).
## New Features
### Professional Logging System
- Add Logger.swift with os.Logger subsystems (cloudkit, datasource, sync)
- Implement --verbose/-v flag for both sync and export commands
- Add educational logging with explain() for teaching CloudKit concepts
- Include verbose(), info(), success(), warning(), error() helpers
- Thread-safe global isVerbose flag with proper Swift 6 concurrency
### Educational Logging Throughout
- SyncEngine: Log sync phases, data pipeline, MistKit batch operations
- BushelCloudKitService: Log dependency ordering, batch details, CloudKit responses
- Verbose mode reveals Server-to-Server auth, batching limits, API calls
- Tutorial comments explaining MistKit patterns and CloudKit concepts
### Tutorial-Quality Documentation
- Add "What You'll Learn" section with 5 key objectives
- Create Quick Start guide with Learning Mode examples
- Document verbose flag usage and benefits
- Add comprehensive troubleshooting section for common beginner mistakes
- Expand Usage section with all command-line flag examples
- Add "Using Bushel as a Reference" guide for copying patterns
- Include learning path for beginners with key files to study
- Link to Celestra sibling demo (coming soon)
## Documentation Improvements
- README expanded from ~430 to ~590 lines
- Added troubleshooting guide with 5 common issues and solutions
- Enhanced learning resources with beginner-focused content
- Documented all reusable patterns (auth, batching, logging, records)
## GitHub Issues Created
Created 5 issues for deferred enhancements:
- #136: Comprehensive test suite
- #137: Incremental sync with change tracking
- #138: Configuration file support (.bushelrc)
- #139: Advanced CloudKit features (deduplication, zones, conflicts)
- #140: Architecture diagrams for documentation
## Task Management
- Completed Task 5 (Bushel Version History Tool) in Task Master
- All subtasks 5.1-5.5 marked complete
- Ready to proceed to Task 6 (Celestra RSS Tool)
## Build Status
- ✅ Zero errors, zero warnings
- ✅ Swift 6 strict concurrency compliant
- ✅ All new code properly annotated
This makes Bushel ready for:
1. Blog Post Part 3 feature with professional screenshots
2. Tutorial resource for novice iOS developers learning CloudKit
3. Reference template for Claude Code implementing Celestra
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: convert boolean to INT64 helper method for CloudKit compatibility
CloudKit Web Services doesn't have a native BOOLEAN type - it uses INT64
with 0/1 values. This change:
- Converts FieldValue.boolean enum case to a static helper method
- Makes isSigned optional in RestoreImageRecord (unknown for some sources)
- Updates RecordBuilder to conditionally include isSigned field
- Improves merge logic to prefer non-nil isSigned values
- Removes dead code from CustomFieldValue
- Cleans up unused imports and OpenAPI type definitions
All tests passing ✅
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(bushel): improve isSigned merge logic and add data source timestamps
Core Improvements:
- Fixed MESU fetcher XML parsing to correctly navigate plist structure
- Added sourceUpdatedAt field to RestoreImageRecord for tracking data freshness
- Implemented sophisticated merge priority: MESU > most recent timestamp > prefer false on conflict
- MrMacintoshFetcher now extracts page update date from HTML
- Fixed Package.swift dependency reference (MistKit-Bushel)
New Features:
- Added ClearCommand for deleting all CloudKit records
- Added deleteAllRecords() and clear() methods to CloudKit services
Data Source Improvements:
- MESU now correctly identifies signed builds (e.g., 25B78 = macOS 26.1)
- Merge logic respects MESU as authoritative regardless of age
- Non-MESU sources compared by sourceUpdatedAt for freshness
- When sources disagree with same timestamp, prefers false (safer)
Documentation:
- Added TODO-AppleDB-LastModified.md for future AppleDB integration
- Documents planned Last-Modified header usage across all fetchers
- Includes complete implementation guide for AppleDB replacement
Technical Details:
- DataSourcePipeline.swift: Lines 176-219 implement merge priority rules
- MESUFetcher.swift: Fixed XML path navigation for VirtualMac2,1
- MrMacintoshFetcher.swift: Parses "UPDATED: MM/DD/YY" from HTML
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(bushel): add HTTP Last-Modified tracking and AppleDB integration
- Add HTTPHeaderHelpers utility for fetching Last-Modified headers from data sources
- Update IPSWFetcher, MESUFetcher, and MrMacintoshFetcher to capture HTTP Last-Modified timestamps
- Add AppleDB as new data source with GitHub commit date tracking for macOS-specific updates
- AppleDBFetcher fetches from api.appledb.dev with device-specific signing status
- Uses GitHub API to track when macOS data was last updated (more accurate than Last-Modified)
- Falls back to HTTP Last-Modified if GitHub API fails
- Handles SDK entries without build numbers gracefully
- Deprecate TheAppleWikiFetcher in favor of AppleDB (more reliable and up-to-date)
- Update DataSourcePipeline to include AppleDB in fetch pipeline
Test results show significant improvements:
- AppleDB contributes 236 images (5x more than ipsw.me)
- All timestamp tracking working correctly across sources
- Merge logic properly prioritizes by sourceUpdatedAt timestamps
- Total unique images: 238 (up from 173)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat(bushel): add data source metadata tracking with fetch throttling
Implement comprehensive metadata tracking system to monitor when data
sources were last fetched and updated, enabling intelligent throttling
to prevent unnecessary API calls.
## New Features
### DataSourceMetadata Model
- Track source name, record type, fetch times, and update times
- Store record counts, fetch durations, and error messages
- Use consistent recordName format: "metadata-{source}-{recordType}"
### CloudKit Schema
- Add DataSourceMetadata record type with queryable fields
- Fields: sourceName, recordTypeName, lastFetchedAt, sourceUpdatedAt,
recordCount, fetchDurationSeconds, lastError
- Note: recordName system field must be marked queryable via Dashboard
### FetchConfiguration System
- Per-source throttling intervals (AppleDB: 6h, MESU: 1h, others: 12h)
- Environment variable override support
- Force fetch bypass option
### DataSourcePipeline Integration
- Wrap all fetcher calls with metadata tracking
- Query existing metadata before fetch
- Check throttling rules before fetching
- Time fetch operations
- Update metadata on success or failure
- Sync metadata to CloudKit
### CLI Enhancements
- Add --force flag to bypass throttling
- Add --min-interval flag to override default intervals
- Add --source flag to fetch from specific source only
- Add status command to view metadata and next fetch times
### StatusCommand
- Display last fetched time with "X ago" formatting
- Show source last updated time
- Report record counts and fetch durations
- Calculate next eligible fetch time
- Support --detailed and --errors-only flags
### FieldValue Extensions
- Convenience accessors for FieldValue enum (stringValue, int64Value, etc.)
- Enable cleaner CloudKit response parsing
## Known Issues
### MistKit Logging Redaction
The KEY_ID_REDACTED replacement in MistKit logging is too aggressive,
redacting critical error information including field names and types
from CloudKit error responses. This makes debugging CloudKit errors
nearly impossible.
See METADATA_TRACKING_STATUS.md for complete implementation details
and debugging steps.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: resolve CloudKit metadata tracking issues and add debug logging
This commit fixes several critical issues preventing DataSourceMetadata records from being created in CloudKit and adds comprehensive debugging capabilities.
## Core Fixes
### CloudKit Field Type Issues
- Add explicit type annotations for INT64 and DOUBLE fields in RecordFieldConverter
- Fix date/timestamp conversion to use integer milliseconds instead of floating-point
- CloudKit DATE/TIME fields require integer milliseconds, not double precision
### Debug Logging Enhancements
- Add MISTKIT_DISABLE_LOG_REDACTION environment variable to disable log redaction
- Add --no-redaction flag to both sync and status commands for easier debugging
- Refine maskKeyIdPattern regex from [A-Za-z0-9]{8,} to [a-fA-F0-9]{40,}
- Previous pattern was too aggressive and redacted legitimate field names
### Package Configuration
- Fix MistKit package reference in Bushel/Package.swift (MistKit-Bushel → MistKit)
## Technical Details
The key issue was that CloudKit TIMESTAMP fields require integer milliseconds, but we were sending double-precision floating-point values. This caused CloudKit to reject records with "Invalid value, expected type TIMESTAMP" errors.
Additionally, INT64 and DOUBLE field types were missing explicit type annotations (type: nil), which CloudKit requires for proper field validation.
The overly broad log redaction pattern was masking actual CloudKit error messages, making debugging impossible. The refined pattern now only redacts actual CloudKit key IDs (40+ hex characters).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: remove obsolete metadata tracking documentation
Remove conversation transcript and status document as all issues have been resolved and the metadata tracking feature is now fully functional.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* docs(bushel): add PR #132 code review fix documentation
Add comprehensive documentation for addressing code review feedback:
- Task Master PRD with 8 prioritized tasks (P0-P2)
- Detailed implementation guide with code examples and acceptance criteria
- Remove obsolete TODO-AppleDB-LastModified.md
Coverage includes:
- Type conversion fixes (Boolean/Int64, safe casting)
- Enhanced error handling and retry logic
- Security improvements (key permissions, logging redaction)
- Code refactoring and complexity reduction
- Validation layers for references and fields
- Batch operation enhancements
- Documentation and performance optimizations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Code Review Fixes (#142)
* refactor: replace RecordFieldConverter with initializer-based conversions
Replace the 363-line RecordFieldConverter utility enum with idiomatic
Swift initializer extensions, resolving all major linting violations.
Changes:
- Add Components.Schemas.FieldValue+FieldValue.swift for MistKit → OpenAPI conversion
- Add FieldValue+Components.swift for OpenAPI → MistKit conversion
- Add CustomFieldValue.CustomFieldValuePayload+FieldValue.swift for list nesting
- Remove RecordFieldConverter.swift (363 lines with 8 serious violations)
- Refactor CloudKitResponseProcessor.processModifyRecordsResponse using static error handler array
- Add CloudKitError.init?(_ response:) with @sendable handlers (complexity reduced from 25 → 3)
- Fix multiline arguments brackets in CloudKitService+WriteOperations.swift
- Remove TODO comment in FieldValue.swift
- Fix public import warning in CustomFieldValuePayload.swift
Benefits:
- More idiomatic Swift API (initializer-based conversions)
- Cleaner call sites: FieldValue(x) vs RecordFieldConverter.convertToFieldValue(x)
- Better maintainability with loop-based error handling
- Zero compilation errors, only minor style warnings remain
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: unify error handling with CloudKitResponseType protocol
Replace operation-specific error handlers with a generic protocol-based approach that works for all CloudKit operations. This reduces code duplication and makes error handling more maintainable.
- Add CloudKitResponseType protocol defining common error response accessors
- Implement protocol conformance for getCurrentUser and modifyRecords operations
- Refactor CloudKitError initializers to use generic protocol-based error extraction
- Remove CloudKitError+ModifyRecords.swift (replaced by generic approach)
- Simplify CloudKitResponseProcessor.processGetCurrentUserResponse
- Add proper copyright headers to operation extension files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent b7f7e9d commit 5386d45
86 files changed
Lines changed: 10056 additions & 295 deletions
File tree
- .taskmaster
- docs
- tasks
- Examples
- Bushel
- Scripts
- Sources/BushelImages
- CloudKit
- Commands
- Configuration
- DataSources
- AppleDB
- TheAppleWiki
- Models
- Models
- Sources/MistDemo/Utilities
- Sources/MistKit
- Authentication
- Generated
- Service
- Utilities
- Tests/MistKitTests/Core/FieldValue
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 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 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
0 commit comments