feat: integrate CocoaPods for macos tactical app and update environment configurations

This commit is contained in:
Hamza-Ayed
2026-08-21 04:12:13 +03:00
parent 7216d86740
commit 4a7859f4c2
6 changed files with 276 additions and 105 deletions
+129 -104
View File
@@ -70,7 +70,8 @@ export class MapsService {
profile: profile,
locale: locale === 'en' ? 'ar' : locale, // Default to Arabic if not specified or fallback
calc_points: true,
points_encoded: true,
points_encoded: false, // JSON arrays for reliable 3D elevation (SRTM)
elevation: true, // ← SRTM: طلب إحداثيات 3D [lng, lat, elevation] + ascend/descend
instructions: steps || true, // Always request instructions to extract route name
};
@@ -160,7 +161,8 @@ export class MapsService {
const hr = now.getHours();
const dow = now.getDay();
const coords = this.decodePolyline(route.points);
const coords3D = this.extractCoords3D(route.points);
const coords: [number, number][] = coords3D.map(c => [c[0], c[1]]); // 2D for traffic grid
const trafficFactor = this.trafficGrid.getTrafficFactor(coords, hr, dow);
const baseDuration = route.time / 1000;
@@ -172,7 +174,8 @@ export class MapsService {
// Process all paths to add metadata (Real Street Names, Tags, Elevation & Slope Warnings, Eco/Fuel metrics)
const processedPaths = paths.map((p: any, index: number) => {
const pCoords = this.decodePolyline(p.points);
const pCoords3D = this.extractCoords3D(p.points);
const pCoords: [number, number][] = pCoords3D.map(c => [c[0], c[1]]); // 2D for traffic grid
const pTrafficFactor = this.trafficGrid.getTrafficFactor(pCoords, hr, dow);
const pBaseDuration = p.time / 1000;
const pDuration = Math.round(pBaseDuration * pTrafficFactor);
@@ -196,8 +199,12 @@ export class MapsService {
finalRouteName = index === 0 ? 'المسار المباشر الأسرع' : 'مسار بديل عبر الطرق الموازية';
}
// Analyze slopes and enrich instructions
const { enrichedInstructions, slopeSummary } = this.enrichInstructionsWithSlopeAnalysis(p.instructions, pCoords);
// Analyze slopes using REAL 3D elevation from SRTM satellite data
const { enrichedInstructions, slopeSummary } = this.enrichInstructionsWithSlopeAnalysis(p.instructions, pCoords3D);
// Override with GraphHopper's authoritative SRTM ascend/descend values when available
if (typeof p.ascend === 'number') slopeSummary.totalAscentMeters = Math.round(p.ascend);
if (typeof p.descend === 'number') slopeSummary.totalDescentMeters = Math.round(p.descend);
// Calculate Energy, Fuel Consumption & Eco Cost (combining Distance + Ascent/Descent Physics + Traffic/Time Delays)
const ecoMetrics = this.calculateEcoAndFuelMetrics(
@@ -229,7 +236,8 @@ export class MapsService {
tags,
distance: p.distance,
duration: pDuration,
points: p.points,
// Return standard Google-encoded Polyline string
points: this.encodePolyline(pCoords3D.map(c => [c[0], c[1]])),
bbox: p.bbox,
instructions: steps ? enrichedInstructions : undefined,
elevationSummary: slopeSummary,
@@ -290,16 +298,27 @@ export class MapsService {
}
/**
* Enriches turn-by-turn routing instructions with steep slope / incline warnings
* Enriches turn-by-turn routing instructions with calibrated slope / incline warnings.
* Uses smoothed REAL SRTM 3D elevation data to eliminate raster quantization noise.
*/
private enrichInstructionsWithSlopeAnalysis(instructions: any[], coords: [number, number][]) {
if (!instructions || !coords || coords.length < 2) {
private enrichInstructionsWithSlopeAnalysis(instructions: any[], rawCoords3D: [number, number, number][]) {
if (!instructions || !rawCoords3D || rawCoords3D.length < 2) {
return {
enrichedInstructions: instructions,
slopeSummary: { totalAscentMeters: 0, totalDescentMeters: 0, maxInclinePercent: 0, maxDeclinePercent: 0, steepWarningsCount: 0, steepWarnings: [] }
};
}
// 1. Apply Gaussian/Weighted 3-point smoothing on elevation to remove SRTM 30m grid noise
const coords3D: [number, number, number][] = rawCoords3D.map((pt, i, arr) => {
if (i === 0 || i === arr.length - 1) return pt;
const prev = arr[i - 1][2];
const curr = pt[2];
const next = arr[i + 1][2];
const smoothedEle = (prev + 2 * curr + next) / 4;
return [pt[0], pt[1], smoothedEle];
});
let totalAscent = 0;
let totalDescent = 0;
let maxInclinePercent = 0;
@@ -308,44 +327,63 @@ export class MapsService {
const enrichedInstructions = instructions.map((inst: any) => {
const interval = inst.interval || [0, 0];
const startIdx = Math.min(interval[0], coords.length - 1);
const endIdx = Math.min(interval[1], coords.length - 1);
const startIdx = Math.min(interval[0], coords3D.length - 1);
const endIdx = Math.min(interval[1], coords3D.length - 1);
// 1. Localize text into 100% fluent Arabic
// Localize text into 100% fluent Arabic
const localizedBaseText = this.localizeInstructionToArabic(inst.text);
if (startIdx < endIdx) {
const c1 = coords[startIdx];
const c2 = coords[endIdx];
const e1 = this.estimateElevation(c1[1], c1[0]);
const e2 = this.estimateElevation(c2[1], c2[0]);
const elevDiff = e2 - e1;
const dist = Math.max(30, inst.distance || this.haversineDistance(c1[1], c1[0], c2[1], c2[0]) || 1);
// Walk segments within this instruction with noise threshold (>= 0.8m)
let stepAscent = 0;
let stepDescent = 0;
for (let i = startIdx; i < endIdx; i++) {
const eDiff = coords3D[i + 1][2] - coords3D[i][2];
if (eDiff >= 0.8) stepAscent += eDiff;
else if (eDiff <= -0.8) stepDescent += Math.abs(eDiff);
}
if (elevDiff > 0.3) totalAscent += elevDiff;
else if (elevDiff < -0.3) totalDescent += Math.abs(elevDiff);
totalAscent += stepAscent;
totalDescent += stepDescent;
// Grade percentage: (rise / run) * 100
const rawSlope = (elevDiff / dist) * 100;
const slopePercent = Math.max(-16, Math.min(16, Math.round(rawSlope)));
// Net elevation change for this instruction
const netElevDiff = coords3D[endIdx][2] - coords3D[startIdx][2];
const dist = Math.max(30, inst.distance || 1);
// Grade percentage: (net rise / run) * 100
const rawSlope = (netElevDiff / dist) * 100;
const clampedRaw = Math.max(-16, Math.min(16, Math.round(rawSlope)));
// Dampen slope severity by 3% as requested (e.g. 13% -> 10%, -13% -> -10%)
let slopePercent = 0;
if (clampedRaw > 0) {
slopePercent = Math.max(0, clampedRaw - 3);
} else if (clampedRaw < 0) {
slopePercent = Math.min(0, clampedRaw + 3);
}
if (slopePercent > maxInclinePercent) maxInclinePercent = slopePercent;
if (slopePercent < maxDeclinePercent) maxDeclinePercent = slopePercent;
// Warning only for steep grades (6% or higher is standard civil road warning threshold)
// Civil road standard: warnings apply to meaningful, sustained grades
// (Distance >= 100m OR significant vertical change >= 12m)
const isSustainedSegment = dist >= 100 || Math.abs(netElevDiff) >= 12;
let warning_ar: string | null = null;
if (slopePercent >= 6) {
warning_ar = `⚠️ تنبيه: صعود حاد (+${slopePercent}%)`;
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'incline', street: inst.street_name });
} else if (slopePercent <= -6) {
warning_ar = `⚠️ تنبيه: منحدر شديد (${slopePercent}%) - خفف السرعة`;
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'decline', street: inst.street_name });
if (isSustainedSegment) {
if (slopePercent >= 8) {
warning_ar = `⚠️ تنبيه: صعود حاد (+${slopePercent}%)`;
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'incline', street: inst.street_name });
} else if (slopePercent <= -8) {
warning_ar = `⚠️ تنبيه: منحدر شديد (${slopePercent}%) - خفف السرعة`;
steepWarnings.push({ text: localizedBaseText, slopePercent, type: 'decline', street: inst.street_name });
}
}
return {
...inst,
slopePercent,
elevationChangeMeters: Math.round(elevDiff),
elevationChangeMeters: Math.round(netElevDiff),
slopeWarning: warning_ar || undefined,
text: warning_ar ? `${localizedBaseText} (${warning_ar})` : localizedBaseText
};
@@ -597,72 +635,7 @@ export class MapsService {
return text;
}
/**
* Universal Analytical Topographic Digital Elevation Model (DEM) for the Entire Map of Jordan.
* Continuous, seamless mathematical surface modeling all provinces, mountain crests, valleys, and plateaus.
*/
private estimateElevation(lat: number, lng: number): number {
// 1. Boundary guard (default fallback for global coordinates outside Jordan)
if (lat < 29.0 || lat > 33.5 || lng < 34.5 || lng > 39.5) {
return 700;
}
// 2. Rift Valley Axis (Wadi Araba, Dead Sea, Jordan Valley)
// The rift axis runs along a slightly tilted meridian (Lng ~35.56 in North, ~35.00 in South)
const riftLng = 35.00 + (lat - 29.5) * (35.56 - 35.00) / (33.0 - 29.5);
const distFromRiftLng = lng - riftLng; // Negative = West of rift, Positive = East of rift
// Elevation along the Rift Valley floor
let riftFloorElev: number;
if (lat >= 32.7) riftFloorElev = -200 + (lat - 32.7) * 200; // Sea of Galilee / Yarmouk (-200m to 0m)
else if (lat >= 31.5) riftFloorElev = -430 + Math.pow((lat - 31.5) / 1.2, 2) * 230; // Dead Sea to Deir Alla (-430m to -200m)
else if (lat >= 30.5) riftFloorElev = -430 + (31.5 - lat) * 450; // Dead Sea south to Gharandal (-430m to +20m)
else riftFloorElev = 20 + (lat - 29.5) * 80; // Wadi Araba to Aqaba (+20m to +100m)
// Crest Elevation of the Eastern Mountain Ridge (Ajloun -> Balqa -> Karak -> Tafila -> Shobak -> Ras En Naqb)
let highlandCrestElev: number;
const crestDistanceDeg = 0.28; // Distance in degrees from Rift axis to the mountain crest (~28 km)
if (lat >= 32.2) highlandCrestElev = 1050 + (lat - 32.2) * 100; // Ajloun / Jerash (1050m - 1200m)
else if (lat >= 31.8) highlandCrestElev = 980 + (lat - 31.8) * 150; // Salt / West Amman (980m - 1040m)
else if (lat >= 31.3) highlandCrestElev = 820 + (lat - 31.3) * 200; // Madaba / Central (820m - 920m)
else if (lat >= 30.7) highlandCrestElev = 1100 + (31.3 - lat) * 400; // Karak / Tafila (1100m - 1340m)
else if (lat >= 29.9) highlandCrestElev = 1450 + (30.7 - lat) * 150; // Dana / Shobak / Ras En Naqb (1450m - 1570m)
else highlandCrestElev = 850 - (29.9 - lat) * 800; // Drop to Aqaba Mountains
// 3. Physical Cross-Section Profile across Jordan (East-West Topography)
let elev: number;
if (distFromRiftLng <= 0) {
// In the Rift or Western escarpment
const wFraction = Math.min(1, Math.abs(distFromRiftLng) / 0.15);
elev = riftFloorElev + (700 - riftFloorElev) * (wFraction * wFraction);
} else if (distFromRiftLng <= crestDistanceDeg) {
// Steep ascent from Rift Valley floor to Mountain Crest
const ascentFraction = distFromRiftLng / crestDistanceDeg; // 0 (Rift) -> 1 (Mountain Crest)
// S-curve steep escarpment (Sigmoid transition)
const sCurve = Math.sin((ascentFraction - 0.5) * Math.PI) * 0.5 + 0.5;
elev = riftFloorElev + (highlandCrestElev - riftFloorElev) * sCurve;
} else {
// East of Mountain Crest: Gentle slope down into the Eastern Plateaus and Basins
const eastDistDeg = distFromRiftLng - crestDistanceDeg;
let easternBasePlateau = 680;
if (lat >= 32.4) easternBasePlateau = 560; // Irbid / Ramtha Plateau
else if (lat >= 31.9) easternBasePlateau = 580; // Amman East / Zarqa Basin
else if (lat >= 31.4) easternBasePlateau = 720; // Airport / Qatranah
else easternBasePlateau = 850; // Maan / Southern Desert Plateau
// Decay from Mountain Crest towards Eastern Base Plateau
const plateauDecay = Math.exp(-eastDistDeg / 0.35);
elev = easternBasePlateau + (highlandCrestElev - easternBasePlateau) * plateauDecay;
// Eastern Desert Azraq depression (Lng 36.8, Lat 31.8)
const azraqDist = Math.hypot((lat - 31.83) * 1.1, (lng - 36.82));
if (azraqDist < 0.6) {
elev -= (1 - azraqDist / 0.6) * 120; // Dips to ~510m in Azraq
}
}
return elev;
}
// estimateElevation REMOVED — replaced by real SRTM satellite data from GraphHopper
private haversineDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
const R = 6371000;
@@ -736,7 +709,62 @@ export class MapsService {
}
/**
* Manual decoder for Google Polyline algorithm (Server-side spatial matching)
* Extracts 3D coordinates from GraphHopper's JSON points response.
* With points_encoded=false and elevation=true, GH returns:
* { type: "LineString", coordinates: [[lng, lat, ele], ...] }
* Returns: [lng, lat, elevation][] — compatible with all coord consumers.
*/
private extractCoords3D(points: any): [number, number, number][] {
if (!points) return [];
// GH returns { type: "LineString", coordinates: [[lng, lat, ele], ...] }
const rawCoords = points.coordinates || points;
if (!Array.isArray(rawCoords)) return [];
return rawCoords.map((c: number[]) => {
// c = [lng, lat, elevation_meters]
return [c[0], c[1], c[2] || 0] as [number, number, number];
});
}
/**
* Encodes array of [lng, lat] coordinates into a standard Google-encoded polyline string.
*/
private encodePolyline(coords: [number, number][], precision: number = 5): string {
if (!coords || coords.length === 0) return '';
const factor = Math.pow(10, precision);
let output = '';
let prevLat = 0;
let prevLng = 0;
const encodeSignedNumber = (num: number): string => {
let sgn_num = num < 0 ? ~(num << 1) : (num << 1);
let encodeString = '';
while (sgn_num >= 0x20) {
encodeString += String.fromCharCode((0x20 | (sgn_num & 0x1f)) + 63);
sgn_num >>= 5;
}
encodeString += String.fromCharCode(sgn_num + 63);
return encodeString;
};
for (const [lng, lat] of coords) {
const latInt = Math.round(lat * factor);
const lngInt = Math.round(lng * factor);
const dLat = latInt - prevLat;
const dLng = lngInt - prevLng;
prevLat = latInt;
prevLng = lngInt;
output += encodeSignedNumber(dLat);
output += encodeSignedNumber(dLng);
}
return output;
}
/**
* Legacy 2D polyline decoder — kept for any encoded polyline contexts
*/
private decodePolyline(encoded: string): [number, number][] {
const points: [number, number][] = [];
@@ -750,18 +778,15 @@ export class MapsService {
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
let dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
lat += ((result & 1) ? ~(result >> 1) : (result >> 1));
shift = 0;
result = 0;
shift = 0; result = 0;
do {
b = encoded.charCodeAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
let dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
lng += ((result & 1) ? ~(result >> 1) : (result >> 1));
points.push([lng * 1e-5, lat * 1e-5]);
}
+2
View File
@@ -56,6 +56,7 @@ services:
memory: 6g
volumes:
- ./infrastructure/osm-data:/data
- graphhopper-srtm-cache:/data/srtm-cache
- ./infrastructure/docker/graphhopper/config.yml:/graphhopper/config.yml
command: ["server", "/graphhopper/config.yml"]
healthcheck:
@@ -191,3 +192,4 @@ services:
volumes:
postgres_data:
redis_data:
graphhopper-srtm-cache:
@@ -14,6 +14,14 @@ graphhopper:
datareader.file: /data/master_map.osm.pbf
graph.location: /data/graph-cache
# ── بيانات الارتفاع الحقيقية (SRTM 30m) ──────────────────────────────
# يحمّل تلقائياً ملفات .hgt من NASA SRTM لتغطية الأردن.
# يربط كل حافة (Edge) في الغراف بارتفاعها الفعلي بالأمتار.
# يُفعّل حقول ascend/descend في الـ Response + إحداثيات 3D.
graph.elevation.provider: srtm
graph.elevation.cache_dir: /data/srtm-cache/
graph.elevation.dataaccess: RAM_STORE
# كانت "" أي: لا تتجاهل شيئاً — فتُستورد الأرصفة والمسارات كحافات ويقفز عليها
# الـ snapping فيخرج مسار غريب بجانب الشارع. نعيد القيمة الافتراضية الآمنة.
import.osm.ignored_highways: "footway,cycleway,path,pedestrian,steps"
+37
View File
@@ -0,0 +1,37 @@
PODS:
- FlutterMacOS (1.0.0)
- geolocator_apple (1.2.0):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- sqflite_darwin (0.0.4):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- geolocator_apple (from `Flutter/ephemeral/.symlinks/plugins/geolocator_apple/darwin`)
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
- sqflite_darwin (from `Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin`)
EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral
geolocator_apple:
:path: Flutter/ephemeral/.symlinks/plugins/geolocator_apple/darwin
shared_preferences_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
sqflite_darwin:
:path: Flutter/ephemeral/.symlinks/plugins/sqflite_darwin/darwin
SPEC CHECKSUMS:
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009
COCOAPODS: 1.16.2
@@ -27,6 +27,8 @@
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
351EDA49D1C5D3D374442256 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A07BE6B1ED52BF54529E45D5 /* Pods_Runner.framework */; };
B9F70418964FC439A80A8172 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84317F6C0B63CE53A0B782E6 /* Pods_RunnerTests.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -60,11 +62,14 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
22C86F6D7064344A3EA3B0F4 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
27F99917FA4EEFF1083B2DEF /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
2D009C51E8F63A859988957D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* tactical_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "tactical_app.app"; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10ED2044A3C60003C045 /* tactical_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = tactical_app.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
@@ -76,8 +81,13 @@
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
52A5FB3D9A5E33ED13FA3342 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
84317F6C0B63CE53A0B782E6 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8CABBDB3B2BA3077BB2517C6 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
A07BE6B1ED52BF54529E45D5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E48D5CA4666E94B1C9420A30 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -85,6 +95,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B9F70418964FC439A80A8172 /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -92,6 +103,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
351EDA49D1C5D3D374442256 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -125,6 +137,7 @@
331C80D6294CF71000263BE5 /* RunnerTests */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
C4E3432204F1BF84835896C3 /* Pods */,
);
sourceTree = "<group>";
};
@@ -172,9 +185,25 @@
path = Runner;
sourceTree = "<group>";
};
C4E3432204F1BF84835896C3 /* Pods */ = {
isa = PBXGroup;
children = (
22C86F6D7064344A3EA3B0F4 /* Pods-Runner.debug.xcconfig */,
2D009C51E8F63A859988957D /* Pods-Runner.release.xcconfig */,
52A5FB3D9A5E33ED13FA3342 /* Pods-Runner.profile.xcconfig */,
E48D5CA4666E94B1C9420A30 /* Pods-RunnerTests.debug.xcconfig */,
8CABBDB3B2BA3077BB2517C6 /* Pods-RunnerTests.release.xcconfig */,
27F99917FA4EEFF1083B2DEF /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
A07BE6B1ED52BF54529E45D5 /* Pods_Runner.framework */,
84317F6C0B63CE53A0B782E6 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -186,6 +215,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
DC5D4041C53A97A05B846521 /* [CP] Check Pods Manifest.lock */,
331C80D1294CF70F00263BE5 /* Sources */,
331C80D2294CF70F00263BE5 /* Frameworks */,
331C80D3294CF70F00263BE5 /* Resources */,
@@ -204,11 +234,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
6200C1F13689F6F2491B9933 /* [CP] Check Pods Manifest.lock */,
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
9E96F183857CC40B7A5816E1 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -329,6 +361,67 @@
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
6200C1F13689F6F2491B9933 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9E96F183857CC40B7A5816E1 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
DC5D4041C53A97A05B846521 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -380,6 +473,7 @@
/* Begin XCBuildConfiguration section */
331C80DB294CF71000263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = E48D5CA4666E94B1C9420A30 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
@@ -394,6 +488,7 @@
};
331C80DC294CF71000263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8CABBDB3B2BA3077BB2517C6 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
@@ -408,6 +503,7 @@
};
331C80DD294CF71000263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 27F99917FA4EEFF1083B2DEF /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
@@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>