From 80d1b3d4e1925167125b6fdf5f45dcc4c41a4bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20G=C3=BCnd=C3=BCz?= Date: Thu, 18 Sep 2025 17:04:56 +0200 Subject: [PATCH 1/4] Initialize CLAUDE.md via /init command --- CLAUDE.md | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c267792 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,75 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This repository maintains a comprehensive dataset of Apple device model identifiers mapped to human-readable names and metadata. It serves as the data source for TelemetryDeck's device detection system. + +## Core Architecture + +### Data Structure +- **Source Data**: Individual JSON files in `dataset/` directory organized by device type: + - `iphones.json` - iPhone models + - `ipads.json` - iPad models + - `macs.json` - Mac models + - `appletvs.json` - Apple TV models + - `wearables.json` - Apple Watch and AirPods + - `other.json` - Other Apple devices + +- **Data Schema**: Each device entry contains: + ```json + { + "ModelIdentifier": { + "deviceType": "Desktop|Laptop|Phone|Tablet|Set-Top Box|Wearable|Headset", + "processorFamily": "Apple M1|Intel Core i5|A15|etc", + "processorType": "Apple Silicon|Intel", + "readableName": "Human readable device name", + "systemFirstRelease": "First OS release version", + "systemLastRelease": "Last supported OS version" + } + } + ``` + +### Processing Pipeline +- **Input**: Multiple JSON files in `dataset/` +- **Processor**: `process.mjs` script that merges all datasets and extracts individual lookup tables +- **Output**: Generated files in `output/` directory for each metadata field: + - `readableName.json` - Model ID → readable name mapping + - `deviceType.json` - Model ID → device type mapping + - `processorType.json` - Model ID → processor type mapping + - `processorFamily.json` - Model ID → processor family mapping + - `systemFirstRelease.json` - Model ID → first release mapping + - `systemLastRelease.json` - Model ID → last release mapping + +## Development Commands + +### Code Formatting +```bash +npx prettier . --check --config .prettierrc.json # Check formatting +npx prettier . --write --config .prettierrc.json # Fix formatting +``` + +### Data Processing +```bash +node process.mjs # Generate lookup tables from dataset files +``` + +### Package Management +```bash +pnpm install # Install dependencies (uses pnpm) +``` + +## CI/CD Pipeline + +The GitHub Actions workflow (`build-pr.yml`) automatically: +1. **Lint**: Runs Prettier formatting checks +2. **Process**: Executes `process.mjs` to generate output files +3. **Release**: Creates automatic releases with generated JSON files (main branch only) + +## Code Style + +- Uses Prettier with custom configuration (`.prettierrc.json`) +- JSON files are automatically sorted recursively +- 4-space indentation, single quotes, no semicolons +- ES modules (`.mjs` extension for Node.js scripts) \ No newline at end of file From 9d07739a97545d3e73cef9757f249266e6224f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20G=C3=BCnd=C3=BCz?= Date: Thu, 18 Sep 2025 17:20:39 +0200 Subject: [PATCH 2/4] Document for Claude Code how to update data properly --- CLAUDE.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index c267792..1efad40 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -72,4 +72,33 @@ The GitHub Actions workflow (`build-pr.yml`) automatically: - Uses Prettier with custom configuration (`.prettierrc.json`) - JSON files are automatically sorted recursively - 4-space indentation, single quotes, no semicolons -- ES modules (`.mjs` extension for Node.js scripts) \ No newline at end of file +- ES modules (`.mjs` extension for Node.js scripts) + +## Data Sources for Updates + +**Primary Sources:** +- **Apple Newsroom** - https://www.apple.com/newsroom/ (official announcements and device names) +- **adamawolf GitHub gist** - https://gist.github.com/adamawolf/3048717 (most up-to-date model identifiers like iPhone18,1) +- **AppleDB** - https://appledb.dev/ (comprehensive device database with SoC info) +- **EveryMac.com** - https://everymac.com/ (detailed technical specifications and processor families) + +**Data Update Process:** +When asked to update data or check for updates: + +1. **Cross-reference sources** - Check adamawolf GitHub gist and AppleDB for new model identifiers +2. **Verify official names** - Confirm device names and specs with Apple Newsroom +3. **Get technical details** - Use EveryMac.com for processor families and device classifications +4. **Update dataset files** in priority order: + - `dataset/iphones.json` (highest priority) + - `dataset/ipads.json` + - `dataset/macs.json` + - `dataset/wearables.json` + - `dataset/appletvs.json` + - `dataset/other.json` +5. **Process and format**: + ```bash + node process.mjs + npx prettier . --write --config .prettierrc.json + ``` + +Always confirm at least 2 sources agree on device information before adding entries. \ No newline at end of file From 07314e28687397a4e287d90ace03834c387d1cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20G=C3=BCnd=C3=BCz?= Date: Thu, 18 Sep 2025 17:33:51 +0200 Subject: [PATCH 3/4] Update all device mappings + add verification instructions for Claude --- CLAUDE.md | 95 +++++++++++++++++++++++++++---------------- dataset/appletvs.json | 12 +++++- dataset/ipads.json | 42 ++++++++++++++++++- dataset/iphones.json | 5 +++ dataset/macs.json | 84 ++++++++++++++++++++++++++++++++++++++ package.json | 2 +- pnpm-lock.yaml | 35 +++++++++------- 7 files changed, 221 insertions(+), 54 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1efad40..2b0d251 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,53 +9,58 @@ This repository maintains a comprehensive dataset of Apple device model identifi ## Core Architecture ### Data Structure + - **Source Data**: Individual JSON files in `dataset/` directory organized by device type: - - `iphones.json` - iPhone models - - `ipads.json` - iPad models - - `macs.json` - Mac models - - `appletvs.json` - Apple TV models - - `wearables.json` - Apple Watch and AirPods - - `other.json` - Other Apple devices + - `iphones.json` - iPhone models + - `ipads.json` - iPad models + - `macs.json` - Mac models + - `appletvs.json` - Apple TV models + - `wearables.json` - Apple Watch and AirPods + - `other.json` - Other Apple devices - **Data Schema**: Each device entry contains: - ```json - { - "ModelIdentifier": { - "deviceType": "Desktop|Laptop|Phone|Tablet|Set-Top Box|Wearable|Headset", - "processorFamily": "Apple M1|Intel Core i5|A15|etc", - "processorType": "Apple Silicon|Intel", - "readableName": "Human readable device name", - "systemFirstRelease": "First OS release version", - "systemLastRelease": "Last supported OS version" + ```json + { + "ModelIdentifier": { + "deviceType": "Desktop|Laptop|Phone|Tablet|Set-Top Box|Wearable|Headset", + "processorFamily": "Apple M1|Intel Core i5|A15|etc", + "processorType": "Apple Silicon|Intel", + "readableName": "Human readable device name", + "systemFirstRelease": "First OS release version", + "systemLastRelease": "Last supported OS version" + } } - } - ``` + ``` ### Processing Pipeline + - **Input**: Multiple JSON files in `dataset/` - **Processor**: `process.mjs` script that merges all datasets and extracts individual lookup tables - **Output**: Generated files in `output/` directory for each metadata field: - - `readableName.json` - Model ID → readable name mapping - - `deviceType.json` - Model ID → device type mapping - - `processorType.json` - Model ID → processor type mapping - - `processorFamily.json` - Model ID → processor family mapping - - `systemFirstRelease.json` - Model ID → first release mapping - - `systemLastRelease.json` - Model ID → last release mapping + - `readableName.json` - Model ID → readable name mapping + - `deviceType.json` - Model ID → device type mapping + - `processorType.json` - Model ID → processor type mapping + - `processorFamily.json` - Model ID → processor family mapping + - `systemFirstRelease.json` - Model ID → first release mapping + - `systemLastRelease.json` - Model ID → last release mapping ## Development Commands ### Code Formatting + ```bash -npx prettier . --check --config .prettierrc.json # Check formatting -npx prettier . --write --config .prettierrc.json # Fix formatting +pnpm prettier . --check --config .prettierrc.json # Check formatting +pnpm prettier . --write --config .prettierrc.json # Fix formatting ``` ### Data Processing + ```bash node process.mjs # Generate lookup tables from dataset files ``` ### Package Management + ```bash pnpm install # Install dependencies (uses pnpm) ``` @@ -63,6 +68,7 @@ pnpm install # Install dependencies (uses pnpm) ## CI/CD Pipeline The GitHub Actions workflow (`build-pr.yml`) automatically: + 1. **Lint**: Runs Prettier formatting checks 2. **Process**: Executes `process.mjs` to generate output files 3. **Release**: Creates automatic releases with generated JSON files (main branch only) @@ -77,6 +83,7 @@ The GitHub Actions workflow (`build-pr.yml`) automatically: ## Data Sources for Updates **Primary Sources:** + - **Apple Newsroom** - https://www.apple.com/newsroom/ (official announcements and device names) - **adamawolf GitHub gist** - https://gist.github.com/adamawolf/3048717 (most up-to-date model identifiers like iPhone18,1) - **AppleDB** - https://appledb.dev/ (comprehensive device database with SoC info) @@ -89,16 +96,32 @@ When asked to update data or check for updates: 2. **Verify official names** - Confirm device names and specs with Apple Newsroom 3. **Get technical details** - Use EveryMac.com for processor families and device classifications 4. **Update dataset files** in priority order: - - `dataset/iphones.json` (highest priority) - - `dataset/ipads.json` - - `dataset/macs.json` - - `dataset/wearables.json` - - `dataset/appletvs.json` - - `dataset/other.json` + - `dataset/iphones.json` (highest priority) + - `dataset/ipads.json` + - `dataset/macs.json` + - `dataset/wearables.json` + - `dataset/appletvs.json` + - `dataset/other.json` 5. **Process and format**: - ```bash - node process.mjs - npx prettier . --write --config .prettierrc.json - ``` -Always confirm at least 2 sources agree on device information before adding entries. \ No newline at end of file + ```bash + node process.mjs + pnpm prettier . --write --config .prettierrc.json + ``` + +6. **Verify changes and quality control**: + + ```bash + git status # Check which files were modified + git diff --name-status # See summary of all changes + git diff dataset/ # Review all dataset changes in detail + git diff --stat # Get statistical summary of changes + ``` + + - **Review all changes carefully** - Ensure only intended additions/modifications were made + - **Verify no devices were accidentally removed** - Check that existing entries are preserved + - **Double-check technical accuracy** - Confirm processor families, device types, and naming conventions + - **Cross-reference with 3rd source** - Optionally verify new entries with EveryMac.com or Apple Support docs + - **Validate data consistency** - Ensure new entries follow the same schema and naming patterns as existing data + +Always confirm at least 2 sources agree on device information before adding entries. diff --git a/dataset/appletvs.json b/dataset/appletvs.json index e0da134..4cd058f 100644 --- a/dataset/appletvs.json +++ b/dataset/appletvs.json @@ -1,4 +1,14 @@ { + "AppleTV11,1": { + "deviceType": "Set-Top Box", + "processorFamily": "A12", + "readableName": "Apple TV 4K (2nd generation)" + }, + "AppleTV14,1": { + "deviceType": "Set-Top Box", + "processorFamily": "A15", + "readableName": "Apple TV 4K (3rd generation)" + }, "AppleTV2,1": { "deviceType": "Set-Top Box", "processorFamily": "S5L8930", @@ -22,6 +32,6 @@ "AppleTV6,2": { "deviceType": "Set-Top Box", "processorFamily": "A10X", - "readableName": "Apple TV 4K" + "readableName": "Apple TV 4K (1st generation)" } } diff --git a/dataset/ipads.json b/dataset/ipads.json index fbcc76c..002161b 100644 --- a/dataset/ipads.json +++ b/dataset/ipads.json @@ -119,6 +119,31 @@ "processorFamily": "A15 Bionic", "readableName": "iPad mini (6th generation) (WiFi)" }, + "iPad14,10": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 13-inch (5th generation) (WiFi+Cellular)" + }, + "iPad14,11": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi)" + }, + "iPad14,12": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi+Cellular)" + }, + "iPad14,13": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi)" + }, + "iPad14,14": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi+Cellular)" + }, "iPad14,2": { "deviceType": "Tablet", "processorFamily": "A15 Bionic", @@ -141,9 +166,24 @@ }, "iPad14,6": { "deviceType": "Tablet", - "processorFamily": "", + "processorFamily": "M2", "readableName": "iPad Pro 12.9-inch (6th generation) (WiFi+Cellular)" }, + "iPad14,7": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 11-inch (5th generation) (WiFi)" + }, + "iPad14,8": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 11-inch (5th generation) (WiFi+Cellular)" + }, + "iPad14,9": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 13-inch (5th generation) (WiFi)" + }, "iPad2,1": { "deviceType": "Tablet", "processorFamily": "A5", diff --git a/dataset/iphones.json b/dataset/iphones.json index 2a99256..2a5200b 100644 --- a/dataset/iphones.json +++ b/dataset/iphones.json @@ -149,6 +149,11 @@ "processorFamily": "A16", "readableName": "iPhone 15" }, + "iPhone15,5": { + "deviceType": "Phone", + "processorFamily": "A16", + "readableName": "iPhone 15 Plus" + }, "iPhone16,1": { "deviceType": "Phone", "processorFamily": "A17 Pro", diff --git a/dataset/macs.json b/dataset/macs.json index 5031365..6d1e666 100644 --- a/dataset/macs.json +++ b/dataset/macs.json @@ -157,6 +157,90 @@ "readableName": "MacBook Pro (16-inch, Nov 2023)", "systemFirstRelease": "12.2" }, + "Mac16,1": { + "deviceType": "Laptop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (14-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,10": { + "deviceType": "Desktop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "Mac mini (2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,11": { + "deviceType": "Desktop", + "processorFamily": "M4 Pro", + "processorType": "Apple Silicon", + "readableName": "Mac mini (2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,12": { + "deviceType": "Laptop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "MacBook Air (13-inch, M4, 2025)", + "systemFirstRelease": "15.0" + }, + "Mac16,13": { + "deviceType": "Laptop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "MacBook Air (15-inch, M4, 2025)", + "systemFirstRelease": "15.0" + }, + "Mac16,2": { + "deviceType": "Desktop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "iMac (24-inch, 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,3": { + "deviceType": "Desktop", + "processorFamily": "M4", + "processorType": "Apple Silicon", + "readableName": "iMac (24-inch, 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,5": { + "deviceType": "Laptop", + "processorFamily": "M4 Max", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (16-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,6": { + "deviceType": "Laptop", + "processorFamily": "M4 Pro", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (14-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,7": { + "deviceType": "Laptop", + "processorFamily": "M4 Pro", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (16-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,8": { + "deviceType": "Laptop", + "processorFamily": "M4 Max", + "processorType": "Apple Silicon", + "readableName": "MacBook Pro (14-inch, Nov 2024)", + "systemFirstRelease": "15.0" + }, + "Mac16,9": { + "deviceType": "Desktop", + "processorFamily": "M4 Max", + "processorType": "Apple Silicon", + "readableName": "Mac Studio (2025)", + "systemFirstRelease": "15.0" + }, "MacBook10,1": { "deviceType": "Laptop", "processorType": "Intel", diff --git a/package.json b/package.json index 588a530..ed9544f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "prettier": "^3.1.0", + "prettier": "^3.6.2", "prettier-plugin-sort-json": "^3.1.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aaa5a82..ef136e4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,19 +1,21 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -devDependencies: - prettier: - specifier: ^3.1.0 - version: 3.1.0 - prettier-plugin-sort-json: - specifier: ^3.1.0 - version: 3.1.0(prettier@3.1.0) +importers: + .: + devDependencies: + prettier: + specifier: ^3.6.2 + version: 3.6.2 + prettier-plugin-sort-json: + specifier: ^3.1.0 + version: 3.1.0(prettier@3.6.2) packages: - /prettier-plugin-sort-json@3.1.0(prettier@3.1.0): + prettier-plugin-sort-json@3.1.0: resolution: { integrity: sha512-eIDEUjwzekiVd+oKrpd0aoACBTp5zOW71wDTNy+qQ5C9Q8oqt9n9wCm4F+SeRZbXfgblh/WYIguJynImlBXrvQ==, @@ -21,15 +23,18 @@ packages: engines: { node: '>=16.0.0' } peerDependencies: prettier: ^3.0.0 - dependencies: - prettier: 3.1.0 - dev: true - /prettier@3.1.0: + prettier@3.6.2: resolution: { - integrity: sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==, + integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==, } engines: { node: '>=14' } hasBin: true - dev: true + +snapshots: + prettier-plugin-sort-json@3.1.0(prettier@3.6.2): + dependencies: + prettier: 3.6.2 + + prettier@3.6.2: {} From 6ca911bedf67a58661815fe2e47be63e7d0c3374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cihat=20G=C3=BCnd=C3=BCz?= Date: Thu, 18 Sep 2025 17:42:38 +0200 Subject: [PATCH 4/4] Update actions to make GitHub Actions CI happy --- .github/workflows/build-pr.yml | 31 ++++++++++++++++++++----------- dataset/ipads.json | 28 ++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 5ec0b67..dcea0fc 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -14,13 +14,17 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: '16.x' - - run: npm install - - run: npx prettier . --check --config .prettierrc.json + node-version: '20.x' + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + - run: pnpm install + - run: pnpm prettier . --check --config .prettierrc.json process: name: Process @@ -28,15 +32,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 + with: + node-version: '20.x' + - name: Setup pnpm + uses: pnpm/action-setup@v4 with: - node-version: '16.x' - - run: npm install + version: 9 + - run: pnpm install - run: node process.mjs - name: Upload artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: generated-lookups path: output @@ -49,9 +57,10 @@ jobs: steps: - name: Set current date as env variable run: echo "NOW=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: generated-lookups + path: . - uses: 'marvinpinto/action-automatic-releases@latest' with: repo_token: '${{ secrets.GITHUB_TOKEN }}' diff --git a/dataset/ipads.json b/dataset/ipads.json index 002161b..ae9e2a1 100644 --- a/dataset/ipads.json +++ b/dataset/ipads.json @@ -121,8 +121,8 @@ }, "iPad14,10": { "deviceType": "Tablet", - "processorFamily": "M4", - "readableName": "iPad Pro 13-inch (5th generation) (WiFi+Cellular)" + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi+Cellular)" }, "iPad14,11": { "deviceType": "Tablet", @@ -170,20 +170,40 @@ "readableName": "iPad Pro 12.9-inch (6th generation) (WiFi+Cellular)" }, "iPad14,7": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi)" + }, + "iPad14,8": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 11-inch (6th generation) (WiFi+Cellular)" + }, + "iPad14,9": { + "deviceType": "Tablet", + "processorFamily": "M2", + "readableName": "iPad Air 13-inch (6th generation) (WiFi)" + }, + "iPad16,3": { "deviceType": "Tablet", "processorFamily": "M4", "readableName": "iPad Pro 11-inch (5th generation) (WiFi)" }, - "iPad14,8": { + "iPad16,4": { "deviceType": "Tablet", "processorFamily": "M4", "readableName": "iPad Pro 11-inch (5th generation) (WiFi+Cellular)" }, - "iPad14,9": { + "iPad16,5": { "deviceType": "Tablet", "processorFamily": "M4", "readableName": "iPad Pro 13-inch (5th generation) (WiFi)" }, + "iPad16,6": { + "deviceType": "Tablet", + "processorFamily": "M4", + "readableName": "iPad Pro 13-inch (5th generation) (WiFi+Cellular)" + }, "iPad2,1": { "deviceType": "Tablet", "processorFamily": "A5",