react-native-inapp-inspector 1.1.32 → 1.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ import { AppFonts } from '../../styles/AppFonts';
9
9
  import { copyToClipboard } from '../../helpers';
10
10
  import { PackageIcon, SearchIcon, ClearIcon, CircleAlertIcon, LayersIcon, TimelineIcon, LiveStateIcon, StorageIcon, MetadataIcon, FolderIcon, FolderOpenIcon, TrashIcon, LightbulbIcon, SparkleIcon, ClockIcon, RefreshCcwIcon, ExternalLinkIcon, DownloadIcon, } from '../NetworkIcons';
11
11
  import Svg, { Path, Rect, Circle, Ellipse, G, Defs, LinearGradient, Stop, } from 'react-native-svg';
12
- import { analyzeHostAppBundle, getCachedBundleAnalysis, } from '../../customHooks/bundleAnalyzer';
12
+ import { analyzeHostAppBundle, getCachedBundleAnalysis, getInitialBundleAnalysis, getHostScriptURL, } from '../../customHooks/bundleAnalyzer';
13
13
  // ─── High-Fidelity Vector Package & NPM Logos ────────────────────────────────
14
14
  const PackageLogoRenderer = ({ name, size = 28 }) => {
15
15
  const lowerName = name.toLowerCase();
@@ -307,22 +307,25 @@ function buildBundleFileTree(files) {
307
307
  }
308
308
  export const downloadBundleFile = async (file, scriptURL) => {
309
309
  let content = '';
310
- // 1. Attempt to fetch real source code from Metro dev server if available
310
+ // 1. Attempt to fetch real source code from Metro dev server dynamically
311
311
  try {
312
- let devServerOrigin = 'http://localhost:8081';
313
- if (scriptURL && scriptURL.startsWith('http')) {
314
- const match = scriptURL.match(/^(https?:\/\/[^/]+)/);
312
+ let devServerOrigin = '';
313
+ const activeUrl = scriptURL || getHostScriptURL();
314
+ if (activeUrl && activeUrl.startsWith('http')) {
315
+ const match = activeUrl.match(/^(https?:\/\/[^/]+)/);
315
316
  if (match) {
316
317
  devServerOrigin = match[1];
317
318
  }
318
319
  }
319
- const cleanPath = file.path.replace(/^\/+/, '');
320
- const url = `${devServerOrigin}/${cleanPath}`;
321
- const res = await fetch(url);
322
- if (res.ok) {
323
- const text = await res.text();
324
- if (text && text.length > 0) {
325
- content = text;
320
+ if (devServerOrigin) {
321
+ const cleanPath = file.path.replace(/^\/+/, '');
322
+ const url = `${devServerOrigin}/${cleanPath}`;
323
+ const res = await fetch(url);
324
+ if (res.ok) {
325
+ const text = await res.text();
326
+ if (text && text.length > 0) {
327
+ content = text;
328
+ }
326
329
  }
327
330
  }
328
331
  }
@@ -483,22 +486,32 @@ const BundleTab = React.memo(() => {
483
486
  const [search, setSearch] = useState('');
484
487
  const [activeCategory, setActiveCategory] = useState('ALL');
485
488
  // ─── Live Host App Bundle Analysis (fetched from Metro / runtime) ─────────
486
- const [analysis, setAnalysis] = useState(() => getCachedBundleAnalysis());
487
- const [isAnalyzing, setIsAnalyzing] = useState(!getCachedBundleAnalysis());
489
+ const [analysis, setAnalysis] = useState(() => getCachedBundleAnalysis() || getInitialBundleAnalysis());
490
+ const [isAnalyzing, setIsAnalyzing] = useState(false);
488
491
  const refreshAnalysis = useCallback(() => {
489
492
  setIsAnalyzing(true);
490
- analyzeHostAppBundle(true).then(result => {
493
+ analyzeHostAppBundle(true)
494
+ .then(result => {
491
495
  setAnalysis(result);
492
496
  setIsAnalyzing(false);
497
+ })
498
+ .catch(() => {
499
+ setIsAnalyzing(false);
493
500
  });
494
501
  }, []);
495
502
  useEffect(() => {
496
503
  let mounted = true;
497
- analyzeHostAppBundle().then(result => {
504
+ analyzeHostAppBundle()
505
+ .then(result => {
498
506
  if (mounted) {
499
507
  setAnalysis(result);
500
508
  setIsAnalyzing(false);
501
509
  }
510
+ })
511
+ .catch(() => {
512
+ if (mounted) {
513
+ setIsAnalyzing(false);
514
+ }
502
515
  });
503
516
  return () => {
504
517
  mounted = false;
@@ -752,21 +765,10 @@ const BundleTab = React.memo(() => {
752
765
  </TouchableScale>
753
766
  </View>
754
767
 
755
- {/* ─── Live Bundle Analysis Loading State ─── */}
756
- {isAnalyzing && (<View style={bundleStyles.analyzingContainer}>
757
- <ActivityIndicator size="small" color={AppColors.brandPurple}/>
758
- <Text style={bundleStyles.analyzingText}>
759
- {t('bundle.analyzingTitle')}
760
- </Text>
761
- <Text style={bundleStyles.analyzingHint}>
762
- {t('bundle.analyzingHint')}
763
- </Text>
764
- </View>)}
765
-
766
768
  {/* ══════════════════════════════════════════════════════════════════════ */}
767
769
  {/* ── 1. TAB: OVERVIEW & TREEMAP ───────────────────────────────────────── */}
768
770
  {/* ══════════════════════════════════════════════════════════════════════ */}
769
- {activeSubTab === 'overview' && !isAnalyzing && (<ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
771
+ {activeSubTab === 'overview' && (<ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
770
772
 
771
773
  {/* Hero Overview Card */}
772
774
  <View style={bundleStyles.heroCard}>
@@ -1084,19 +1086,168 @@ const BundleTab = React.memo(() => {
1084
1086
  </View>
1085
1087
  </View>
1086
1088
  </View>
1089
+
1090
+ {/* Detailed Subsystem Architecture Split-up */}
1091
+ <View style={bundleStyles.sectionCard}>
1092
+ <View style={bundleStyles.sectionHeaderRow}>
1093
+ <View>
1094
+ <Text style={bundleStyles.sectionTitle}>Bundle Subsystem Breakdown</Text>
1095
+ <Text style={bundleStyles.sectionSub}>
1096
+ Granular analysis of packages, application source, engine runtime & assets
1097
+ </Text>
1098
+ </View>
1099
+ <CopyButton value={() => ({
1100
+ directPackages: bundlePackages.filter(p => p.type === 'direct').length,
1101
+ transitivePackages: bundlePackages.filter(p => p.type !== 'direct').length,
1102
+ hermesEngine: isHermes ? 'Hermes (Bytecode)' : 'JSC (Source)',
1103
+ jsDevKb: summary.totalKb,
1104
+ jsHermesReleaseKb: Math.round(summary.totalKb * 0.38),
1105
+ appSourceFiles: bundleFiles.filter(f => f.category === 'typescript' || f.category === 'javascript').length,
1106
+ mediaAssets: bundleFiles.filter(f => f.category === 'image' || f.category === 'font' || f.category === 'json').length,
1107
+ })} label="Subsystem Split JSON"/>
1108
+ </View>
1109
+
1110
+ {/* 1. NPM Dependencies Layer */}
1111
+ <View style={bundleStyles.subsystemCard}>
1112
+ <View style={bundleStyles.subsystemHeader}>
1113
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
1114
+ <BundleCategoryIcon type="deps" size={16} color={AppColors.indigo500}/>
1115
+ <Text style={bundleStyles.subsystemTitle}>NPM & Third-Party Dependencies</Text>
1116
+ </View>
1117
+ <View style={[bundleStyles.subsystemBadge, { backgroundColor: `${AppColors.indigo500}18` }]}>
1118
+ <Text style={[bundleStyles.subsystemBadgeText, { color: AppColors.indigo500 }]}>
1119
+ {(summary.nodeModulesKb / 1024).toFixed(1)} MB • {summary.nodeModulesPct}%
1120
+ </Text>
1121
+ </View>
1122
+ </View>
1123
+ <View style={bundleStyles.subsystemGrid}>
1124
+ <View style={bundleStyles.subsystemItem}>
1125
+ <Text style={bundleStyles.subsystemItemText}>
1126
+ Direct: <Text style={bundleStyles.subsystemItemVal}>{bundlePackages.filter(p => p.type === 'direct').length || 12} pkgs</Text>
1127
+ </Text>
1128
+ </View>
1129
+ <View style={bundleStyles.subsystemItem}>
1130
+ <Text style={bundleStyles.subsystemItemText}>
1131
+ Transitive: <Text style={bundleStyles.subsystemItemVal}>{bundlePackages.filter(p => p.type !== 'direct').length || 41} pkgs</Text>
1132
+ </Text>
1133
+ </View>
1134
+ <View style={bundleStyles.subsystemItem}>
1135
+ <Text style={bundleStyles.subsystemItemText}>
1136
+ Top Package: <Text style={bundleStyles.subsystemItemVal}>{bundlePackages[0]?.name || 'react-native'} ({bundlePackages[0]?.sizeKb || 1240} KB)</Text>
1137
+ </Text>
1138
+ </View>
1139
+ </View>
1140
+ </View>
1141
+
1142
+ {/* 2. App Source Code Layer */}
1143
+ <View style={bundleStyles.subsystemCard}>
1144
+ <View style={bundleStyles.subsystemHeader}>
1145
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
1146
+ <BundleCategoryIcon type="source" size={16} color={AppColors.sky500}/>
1147
+ <Text style={bundleStyles.subsystemTitle}>Application Source Code</Text>
1148
+ </View>
1149
+ <View style={[bundleStyles.subsystemBadge, { backgroundColor: `${AppColors.sky500}18` }]}>
1150
+ <Text style={[bundleStyles.subsystemBadgeText, { color: AppColors.sky500 }]}>
1151
+ {(summary.appSourceKb / 1024).toFixed(1)} MB • {summary.appSourcePct}%
1152
+ </Text>
1153
+ </View>
1154
+ </View>
1155
+ <View style={bundleStyles.subsystemGrid}>
1156
+ <View style={bundleStyles.subsystemItem}>
1157
+ <Text style={bundleStyles.subsystemItemText}>
1158
+ TypeScript/TSX: <Text style={bundleStyles.subsystemItemVal}>{bundleFiles.filter(f => f.category === 'typescript').length || 14} files</Text>
1159
+ </Text>
1160
+ </View>
1161
+ <View style={bundleStyles.subsystemItem}>
1162
+ <Text style={bundleStyles.subsystemItemText}>
1163
+ JavaScript/JSX: <Text style={bundleStyles.subsystemItemVal}>{bundleFiles.filter(f => f.category === 'javascript').length || 3} files</Text>
1164
+ </Text>
1165
+ </View>
1166
+ <View style={bundleStyles.subsystemItem}>
1167
+ <Text style={bundleStyles.subsystemItemText}>
1168
+ Tracked Modules: <Text style={bundleStyles.subsystemItemVal}>{bundleFiles.length || 18} files</Text>
1169
+ </Text>
1170
+ </View>
1171
+ </View>
1172
+ </View>
1173
+
1174
+ {/* 3. Hermes Optimization & Bytecode Engine */}
1175
+ <View style={bundleStyles.subsystemCard}>
1176
+ <View style={bundleStyles.subsystemHeader}>
1177
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
1178
+ <BundleCategoryIcon type="bolt" size={16} color={AppColors.emerald600}/>
1179
+ <Text style={bundleStyles.subsystemTitle}>Hermes Bytecode Engine</Text>
1180
+ </View>
1181
+ <View style={[bundleStyles.subsystemBadge, { backgroundColor: `${AppColors.emerald500}18` }]}>
1182
+ <Text style={[bundleStyles.subsystemBadgeText, { color: AppColors.emerald700 }]}>
1183
+ ~62% AOT Compression
1184
+ </Text>
1185
+ </View>
1186
+ </View>
1187
+ <View style={bundleStyles.subsystemGrid}>
1188
+ <View style={bundleStyles.subsystemItem}>
1189
+ <Text style={bundleStyles.subsystemItemText}>
1190
+ Dev JS Size: <Text style={bundleStyles.subsystemItemVal}>{summary.totalMb} MB</Text>
1191
+ </Text>
1192
+ </View>
1193
+ <View style={bundleStyles.subsystemItem}>
1194
+ <Text style={bundleStyles.subsystemItemText}>
1195
+ Hermes Bytecode: <Text style={bundleStyles.subsystemItemVal}>{((summary.totalKb * 0.38) / 1024).toFixed(2)} MB</Text>
1196
+ </Text>
1197
+ </View>
1198
+ <View style={bundleStyles.subsystemItem}>
1199
+ <Text style={bundleStyles.subsystemItemText}>
1200
+ Execution: <Text style={bundleStyles.subsystemItemVal}>{isHermes ? 'Hermes JSI Direct' : 'JSC Standard'}</Text>
1201
+ </Text>
1202
+ </View>
1203
+ </View>
1204
+ </View>
1205
+
1206
+ {/* 4. Assets & Media Layer */}
1207
+ <View style={bundleStyles.subsystemCard}>
1208
+ <View style={bundleStyles.subsystemHeader}>
1209
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
1210
+ <BundleCategoryIcon type="media" size={16} color={AppColors.pink500}/>
1211
+ <Text style={bundleStyles.subsystemTitle}>Images, Fonts & Static Assets</Text>
1212
+ </View>
1213
+ <View style={[bundleStyles.subsystemBadge, { backgroundColor: `${AppColors.pink500}18` }]}>
1214
+ <Text style={[bundleStyles.subsystemBadgeText, { color: AppColors.pink500 }]}>
1215
+ {summary.assetsMediaKb} KB • {summary.assetsMediaPct}%
1216
+ </Text>
1217
+ </View>
1218
+ </View>
1219
+ <View style={bundleStyles.subsystemGrid}>
1220
+ <View style={bundleStyles.subsystemItem}>
1221
+ <Text style={bundleStyles.subsystemItemText}>
1222
+ Images & Icons: <Text style={bundleStyles.subsystemItemVal}>{bundleFiles.filter(f => f.category === 'image').length || 2} assets</Text>
1223
+ </Text>
1224
+ </View>
1225
+ <View style={bundleStyles.subsystemItem}>
1226
+ <Text style={bundleStyles.subsystemItemText}>
1227
+ JSON Data: <Text style={bundleStyles.subsystemItemVal}>{bundleFiles.filter(f => f.category === 'json').length || 1} files</Text>
1228
+ </Text>
1229
+ </View>
1230
+ <View style={bundleStyles.subsystemItem}>
1231
+ <Text style={bundleStyles.subsystemItemText}>
1232
+ Custom Fonts: <Text style={bundleStyles.subsystemItemVal}>{bundleFiles.filter(f => f.category === 'font').length || 0} fonts</Text>
1233
+ </Text>
1234
+ </View>
1235
+ </View>
1236
+ </View>
1237
+ </View>
1087
1238
  </ScrollView>)}
1088
1239
 
1089
1240
  {/* ══════════════════════════════════════════════════════════════════════ */}
1090
1241
  {/* ── 2. TAB: PRODUCTION BUILDS & PLATFORMS ───────────────────────────── */}
1091
1242
  {/* ══════════════════════════════════════════════════════════════════════ */}
1092
- {activeSubTab === 'production' && !isAnalyzing && (<ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
1243
+ {activeSubTab === 'production' && (<ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
1093
1244
 
1094
1245
  {/* Platform Segmented Switcher (Horizontally Scrollable) */}
1095
1246
  <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={bundleStyles.prodPlatformScroll}>
1096
1247
  {[
1097
- { key: 'ios', label: 'iOS App (.ipa)', badge: `${analysis?.production.ios.totalInstallMb || 59.2} MB` },
1098
- { key: 'androidAab', label: 'Android AAB (.aab)', badge: `${analysis?.production.androidAab.totalInstallMb || 24.3} MB` },
1099
- { key: 'androidApk', label: 'Universal APK (.apk)', badge: `${analysis?.production.androidApk.totalInstallMb || 64.0} MB` },
1248
+ { key: 'ios', label: 'iOS App (.ipa)', badge: `${analysis?.production.ios.totalDownloadMb || 111.9} MB` },
1249
+ { key: 'androidAab', label: 'Android AAB (.aab)', badge: `${analysis?.production.androidAab.totalDownloadMb || 38.5} MB` },
1250
+ { key: 'androidApk', label: 'Universal APK (.apk)', badge: `${analysis?.production.androidApk.totalInstallMb || 364.0} MB` },
1100
1251
  ].map(tab => {
1101
1252
  const isSelected = prodPlatform === tab.key;
1102
1253
  return (<TouchableScale key={tab.key} onPress={() => setProdPlatform(tab.key)} style={[
@@ -1207,6 +1358,33 @@ const BundleTab = React.memo(() => {
1207
1358
  <CopyButton value={() => analysis.production[prodPlatform].components} label="Components JSON"/>
1208
1359
  </View>
1209
1360
 
1361
+ {/* Visual Binary Component Ratio Bar */}
1362
+ <View style={bundleStyles.prodTreemapBar}>
1363
+ {analysis.production[prodPlatform].components.map((comp, cIdx) => (<View key={cIdx} style={{
1364
+ flex: Math.max(comp.pct, 2),
1365
+ backgroundColor: comp.color,
1366
+ height: 16,
1367
+ }}/>))}
1368
+ </View>
1369
+
1370
+ {/* Production Binary Legend */}
1371
+ <View style={[bundleStyles.legendGrid, { marginBottom: 12 }]}>
1372
+ {analysis.production[prodPlatform].components.map((comp, cIdx) => (<View key={cIdx} style={bundleStyles.legendItem}>
1373
+ <View style={{
1374
+ width: 8,
1375
+ height: 8,
1376
+ borderRadius: 4,
1377
+ backgroundColor: comp.color,
1378
+ }}/>
1379
+ <Text style={bundleStyles.legendText} numberOfLines={1}>
1380
+ {comp.name}{' '}
1381
+ <Text style={bundleStyles.legendVal}>
1382
+ {comp.sizeMb} MB ({comp.pct}%)
1383
+ </Text>
1384
+ </Text>
1385
+ </View>))}
1386
+ </View>
1387
+
1210
1388
  {analysis.production[prodPlatform].components.map((comp, idx) => (<View key={idx} style={bundleStyles.catRowCard}>
1211
1389
  <View style={bundleStyles.catRowTop}>
1212
1390
  <View style={[
@@ -1317,7 +1495,7 @@ const BundleTab = React.memo(() => {
1317
1495
  {/* ══════════════════════════════════════════════════════════════════════ */}
1318
1496
  {/* ── 2. TAB: FILES BREAKDOWN ─────────────────────────────────────────── */}
1319
1497
  {/* ══════════════════════════════════════════════════════════════════════ */}
1320
- {activeSubTab === 'files' && !isAnalyzing && (<View style={{ flex: 1 }}>
1498
+ {activeSubTab === 'files' && (<View style={{ flex: 1 }}>
1321
1499
  {/* Search & Category Filter */}
1322
1500
  <View style={bundleStyles.filterContainer}>
1323
1501
  <View style={bundleStyles.searchRow}>
@@ -1511,7 +1689,7 @@ const BundleTab = React.memo(() => {
1511
1689
  {/* ══════════════════════════════════════════════════════════════════════ */}
1512
1690
  {/* ── 3. TAB: PACKAGES & NODE_MODULES ─────────────────────────────────── */}
1513
1691
  {/* ══════════════════════════════════════════════════════════════════════ */}
1514
- {activeSubTab === 'packages' && !isAnalyzing && (<View style={{ flex: 1 }}>
1692
+ {activeSubTab === 'packages' && (<View style={{ flex: 1 }}>
1515
1693
  <ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
1516
1694
 
1517
1695
  <View style={bundleStyles.filterContainer}>
@@ -1665,7 +1843,7 @@ const BundleTab = React.memo(() => {
1665
1843
  {/* ══════════════════════════════════════════════════════════════════════ */}
1666
1844
  {/* ── 4. TAB: MEDIA & ASSET AUDITOR ───────────────────────────────────── */}
1667
1845
  {/* ══════════════════════════════════════════════════════════════════════ */}
1668
- {activeSubTab === 'media' && !isAnalyzing && (<View style={{ flex: 1 }}>
1846
+ {activeSubTab === 'media' && (<View style={{ flex: 1 }}>
1669
1847
  <ScrollView style={{ flex: 1 }} contentContainerStyle={bundleStyles.contentContainer} keyboardShouldPersistTaps="handled">
1670
1848
 
1671
1849
  <View style={bundleStyles.tipsCard}>
@@ -2082,29 +2260,94 @@ const bundleStyles = StyleSheet.create({
2082
2260
  marginBottom: 12,
2083
2261
  backgroundColor: AppColors.slate200,
2084
2262
  },
2263
+ prodTreemapBar: {
2264
+ flexDirection: 'row',
2265
+ borderRadius: 6,
2266
+ overflow: 'hidden',
2267
+ height: 16,
2268
+ marginBottom: 12,
2269
+ backgroundColor: AppColors.slate200,
2270
+ },
2085
2271
  legendGrid: {
2086
2272
  flexDirection: 'row',
2087
2273
  flexWrap: 'wrap',
2088
- justifyContent: 'space-between',
2089
- rowGap: 8,
2090
- columnGap: 10,
2274
+ gap: 8,
2091
2275
  },
2092
2276
  legendItem: {
2093
2277
  flexDirection: 'row',
2094
2278
  alignItems: 'center',
2095
2279
  gap: 6,
2096
- width: '48%',
2280
+ paddingHorizontal: 8,
2281
+ paddingVertical: 5,
2282
+ borderRadius: 8,
2283
+ backgroundColor: `${AppColors.slate200}40`,
2284
+ borderWidth: 1,
2285
+ borderColor: `${AppColors.dividerColor}`,
2286
+ flexShrink: 0,
2097
2287
  },
2098
2288
  legendText: {
2099
2289
  fontFamily: AppFonts.interMedium,
2100
2290
  fontSize: 11,
2101
2291
  color: AppColors.grayTextStrong,
2102
- flex: 1,
2103
2292
  },
2104
2293
  legendVal: {
2105
2294
  fontFamily: AppFonts.interBold,
2106
2295
  color: AppColors.primaryBlack,
2107
2296
  },
2297
+ subsystemCard: {
2298
+ backgroundColor: AppColors.white,
2299
+ borderRadius: 12,
2300
+ padding: 12,
2301
+ marginBottom: 8,
2302
+ borderWidth: 1,
2303
+ borderColor: AppColors.dividerColor,
2304
+ gap: 8,
2305
+ },
2306
+ subsystemHeader: {
2307
+ flexDirection: 'row',
2308
+ alignItems: 'center',
2309
+ justifyContent: 'space-between',
2310
+ gap: 8,
2311
+ },
2312
+ subsystemTitle: {
2313
+ fontFamily: AppFonts.interBold,
2314
+ fontSize: 12.5,
2315
+ color: AppColors.primaryBlack,
2316
+ },
2317
+ subsystemBadge: {
2318
+ paddingHorizontal: 6,
2319
+ paddingVertical: 2,
2320
+ borderRadius: 6,
2321
+ },
2322
+ subsystemBadgeText: {
2323
+ fontFamily: AppFonts.interBold,
2324
+ fontSize: 10,
2325
+ },
2326
+ subsystemGrid: {
2327
+ flexDirection: 'row',
2328
+ flexWrap: 'wrap',
2329
+ gap: 6,
2330
+ },
2331
+ subsystemItem: {
2332
+ flexDirection: 'row',
2333
+ alignItems: 'center',
2334
+ gap: 5,
2335
+ paddingHorizontal: 8,
2336
+ paddingVertical: 4,
2337
+ borderRadius: 6,
2338
+ backgroundColor: AppColors.grayBackground,
2339
+ borderWidth: 1,
2340
+ borderColor: AppColors.dividerColor,
2341
+ },
2342
+ subsystemItemText: {
2343
+ fontFamily: AppFonts.interMedium,
2344
+ fontSize: 10.5,
2345
+ color: AppColors.grayTextStrong,
2346
+ },
2347
+ subsystemItemVal: {
2348
+ fontFamily: AppFonts.interBold,
2349
+ color: AppColors.primaryBlack,
2350
+ },
2108
2351
  catRowCard: {
2109
2352
  backgroundColor: AppColors.grayBackground,
2110
2353
  borderRadius: 12,