{"version":3,"file":"API.CGuhnZHy.mjs","names":[],"sources":["https:/framerusercontent.com/modules/vsUFLrh6zDP8ehsYHBc4/4tE9WjvrRxDc1mH0ELIK/MpgCalculation.js","https:/framerusercontent.com/modules/jXi0FPiL6t5NPBGq2SVv/1d5pN1tFeyU1kLCEu0m8/API.js"],"sourcesContent":["function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}// MCP COMPATIBILITY. SEE FOOTER.\n// ============================================================\n// CONSTANTS (from telematic_connection_base.py)\n// ============================================================\nexport const KM_PER_MILE=1.60934;export const LITERS_PER_GALLON=3.78541;export const MIN_TESTABLE_KM_PER_HOUR=.1;export const MIN_TESTABLE_LITERS_PER_HOUR=.1;export const MIN_TESTABLE_KM_PER_LITER=.1;export const MAX_TESTABLE_KM_PER_LITER=50;export const METERS_PER_MILE=KM_PER_MILE*1e3;// ============================================================\n// DATETIME INTERPOLATOR\n// ============================================================\n/**\n * Simple linear interpolator for time series data.\n * Converts timestamps to seconds since epoch and performs linear interpolation.\n * \n * Args:\n *     timestamps: Array of Date objects\n *     values: Array of numeric values to interpolate\n */export class DatetimeInterpolator{/**\n     * Interpolate value at a single timestamp.\n     * \n     * Args:\n     *     timestamp: Date object to interpolate at\n     * \n     * Returns:\n     *     Interpolated value\n     */interpolateAt(timestamp){const targetSeconds=timestamp.getTime()/1e3;// If before first point, use first value\nif(targetSeconds<=this.secondsSinceEpoch[0]){return this.values[0];}// If after last point, use last value\nif(targetSeconds>=this.secondsSinceEpoch[this.secondsSinceEpoch.length-1]){return this.values[this.values.length-1];}// Find the two points to interpolate between\nfor(let i=1;i<this.secondsSinceEpoch.length;i++){if(targetSeconds<=this.secondsSinceEpoch[i]){// Linear interpolation\nconst x0=this.secondsSinceEpoch[i-1];const x1=this.secondsSinceEpoch[i];const y0=this.values[i-1];const y1=this.values[i];const ratio=(targetSeconds-x0)/(x1-x0);return y0+ratio*(y1-y0);}}// Should never reach here\nreturn this.values[this.values.length-1];}/**\n     * Interpolate values at multiple timestamps.\n     * \n     * Args:\n     *     timestamps: Array of Date objects\n     * \n     * Returns:\n     *     Array of interpolated values\n     */interpolate(timestamps){return timestamps.map(t=>this.interpolateAt(t));}constructor(timestamps,values){_define_property(this,\"timestamps\",void 0);_define_property(this,\"values\",void 0);_define_property(this,\"secondsSinceEpoch\",void 0);if(timestamps.length!==values.length){throw new Error(`Timestamps and values must have same length: ${timestamps.length} vs ${values.length}`);}if(timestamps.length===0){throw new Error(\"Timestamps and values cannot be empty\");}this.timestamps=timestamps;this.values=values;// Convert to seconds since epoch\nthis.secondsSinceEpoch=timestamps.map(t=>t.getTime()/1e3);}}// ============================================================\n// MPG CALCULATION\n// ============================================================\n/**\n * Calculate MPG from odometer and fuel time series data.\n * \n * This is a direct port of the Python function in\n * ferox-systems-backend-v3/app/services/geotab_connection/mpg_calculation.py\n * \n * Args:\n *     odometerDates: Timestamps for odometer readings\n *     odometerValues: Odometer values in meters\n *     fuelDates: Timestamps for fuel readings\n *     fuelValues: Fuel values in liters\n *     startDate: Start of analysis period\n *     endDate: End of analysis period\n *     sampleIntervalSeconds: Sampling interval in seconds (default: 900 = 15 min)\n * \n * Returns:\n *     Object with dates and mpg_values arrays\n * \n * Raises:\n *     Error: If data is invalid\n */export function calculateMpgFromTimeSeries(odometerDates,odometerValues,fuelDates,fuelValues,startDate,endDate,sampleIntervalSeconds=900){// Validate inputs\nif(startDate>=endDate){throw new Error(`Start date must be before end date: ${startDate.toISOString()} >= ${endDate.toISOString()}`);}if(odometerDates.length===0||fuelDates.length===0||odometerValues.length===0||fuelValues.length===0){return{dates:[],mpg_values:[]};}if(odometerDates.length!==odometerValues.length){throw new Error(`Odometer dates and values must have same length: ${odometerDates.length} vs ${odometerValues.length}`);}if(fuelDates.length!==fuelValues.length){throw new Error(`Fuel dates and values must have same length: ${fuelDates.length} vs ${fuelValues.length}`);}// Create interpolators\nconst odomInterpolator=new DatetimeInterpolator(odometerDates,odometerValues);const fuelInterpolator=new DatetimeInterpolator(fuelDates,fuelValues);// Determine actual time range available in data\nconst firstTime=new Date(Math.max(Math.min(...odometerDates.map(d=>d.getTime())),Math.min(...fuelDates.map(d=>d.getTime()))));const lastTime=new Date(Math.min(Math.max(...odometerDates.map(d=>d.getTime())),Math.max(...fuelDates.map(d=>d.getTime()))));// Adjust start/end dates to available data range\nconst actualStart=new Date(Math.max(startDate.getTime(),firstTime.getTime()));const actualEnd=new Date(Math.min(endDate.getTime(),lastTime.getTime()));if(actualStart>=actualEnd){return{dates:[],mpg_values:[]};}// Generate sample times\nconst sampleTimes=[];let currentTime=actualStart.getTime();const endTime=actualEnd.getTime();const intervalMs=sampleIntervalSeconds*1e3;while(currentTime<=endTime){sampleTimes.push(new Date(currentTime));currentTime+=intervalMs;}if(sampleTimes.length===0){return{dates:[],mpg_values:[]};}// Interpolate data at sample times\nconst odometerInterpolated=odomInterpolator.interpolate(sampleTimes);const fuelInterpolated=fuelInterpolator.interpolate(sampleTimes);if(sampleTimes.length<2){return{dates:[],mpg_values:[]};}// Calculate thresholds based on sample interval\nconst hours=sampleIntervalSeconds/3600;const minDistM=MIN_TESTABLE_KM_PER_HOUR*1e3*hours;const minFuelL=MIN_TESTABLE_LITERS_PER_HOUR*hours;const dates=[];const mpgValues=[];// Calculate MPG for each interval\nfor(let i=1;i<sampleTimes.length;i++){const distM=odometerInterpolated[i]-odometerInterpolated[i-1];const fuelL=fuelInterpolated[i]-fuelInterpolated[i-1];const meetsMovementThreshold=distM>=minDistM;const meetsFuelThreshold=fuelL>=minFuelL;if(meetsMovementThreshold&&meetsFuelThreshold){// Calculate km/L for efficiency check\nconst km=distM/1e3;const kmPerL=km/fuelL;const aboveMinEffThreshold=kmPerL>=MIN_TESTABLE_KM_PER_LITER;const belowMaxEffThreshold=kmPerL<=MAX_TESTABLE_KM_PER_LITER;if(aboveMinEffThreshold&&belowMaxEffThreshold){const miles=distM/METERS_PER_MILE;const gallons=fuelL/LITERS_PER_GALLON;dates.push(sampleTimes[i]);mpgValues.push(miles/gallons);}}}return{dates,mpg_values:mpgValues};}/**\n * MCP COMPATIBILITY FOOTER. DO NOT MODIFY.\n * FEROX SYSTEMS 2025\n * @framerDisableUnlink\n */export function withMcp(Component){return Component;}\nexport const __FramerMetadata__ = {\"exports\":{\"MIN_TESTABLE_KM_PER_LITER\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"DatetimeInterpolator\":{\"type\":\"class\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"LITERS_PER_GALLON\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"KM_PER_MILE\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"MpgTimeSeries\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"MAX_TESTABLE_KM_PER_LITER\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"MIN_TESTABLE_LITERS_PER_HOUR\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"MIN_TESTABLE_KM_PER_HOUR\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"METERS_PER_MILE\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withMcp\":{\"type\":\"reactHoc\",\"name\":\"withMcp\",\"annotations\":{\"framerContractVersion\":\"1\",\"framerDisableUnlink\":\"\"}},\"calculateMpgFromTimeSeries\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./MpgCalculation.map","/**\n * Analysis API - Functions for the pilot analysis journey\n *\n * API flow:\n * 1. getMpgHistory - Fetch 15-minute resolution MPG data\n * 2. getSingleTruckPlot - Generate PNG timeseries for quality inspection\n * 3. getQualityCheck - Get data quality metrics\n * 4. getImpactEstimate - Run statistical analysis (regression)\n * 5. getComparisonPlot - Generate treatment comparison PNG\n * 6. getPredictionPlot - Generate per-truck prediction PNG\n */import{API_URL}from\"https://framerusercontent.com/modules/SwQjqWc6j32r4pQLdM35/uX7wTJ9jsSCOQYqT068Y/Constants.js\";import{apiPost}from\"https://framerusercontent.com/modules/AAXvLQIFKKh9GsTWu6EG/rAHAKNIDUeW6aHKkIL7V/Api.js\";import{loadUploadedData}from\"https://framerusercontent.com/modules/Q70GysxGEEGNZ5kgxFcP/CYjjkbuAdjCJtQ89rYU9/LocalStorage.js\";import{calculateMpgFromTimeSeries}from\"https://framerusercontent.com/modules/vsUFLrh6zDP8ehsYHBc4/4tE9WjvrRxDc1mH0ELIK/MpgCalculation.js\";// ===== Constants =====\n// 15-minute sampling for analysis (900 seconds)\nexport const ANALYSIS_SAMPLE_INTERVAL_SECONDS=3600;// Default study period (6 months)\nexport function getDefaultStudyDates(){const endDate=new Date;const startDate=new Date;startDate.setMonth(startDate.getMonth()-6);return{startDate,endDate};}// ===== Data Validation =====\n/**\n * Check if an MpgHistory has usable data.\n * Returns false if dates or mpg_readings are empty/missing.\n */export function hasValidMpgData(history){return history!=null&&Array.isArray(history.dates)&&history.dates.length>0&&Array.isArray(history.mpg_readings)&&history.mpg_readings.length>0;}// ===== Manual Upload Helper =====\n/**\n * Get MPG history from manually uploaded CSV data.\n * \n * Args:\n *     truck: Truck object with id matching uploaded data\n *     startDate: Start of analysis period\n *     endDate: End of analysis period\n * \n * Returns:\n *     MpgHistory object with calculated MPG values\n * \n * Raises:\n *     Error: If no uploaded data found or truck not in data\n */function getMpgHistoryFromUpload(truck,startDate,endDate){// Load uploaded data from localStorage\nconst uploadData=loadUploadedData();if(!uploadData){throw new Error(\"No uploaded data found. Please upload CSV files first.\");}// Find truck data\nconst truckData=uploadData.truckData[truck.id];if(!truckData){throw new Error(`Truck ${truck.id} not found in uploaded data. Available trucks: ${Object.keys(uploadData.truckData).join(\", \")}`);}// Convert ISO string dates to Date objects\nconst odometerDates=truckData.odometer.dates.map(d=>new Date(d));const fuelDates=truckData.fuel.dates.map(d=>new Date(d));// Calculate MPG using client-side implementation\nconst mpgResult=calculateMpgFromTimeSeries(odometerDates,truckData.odometer.values,fuelDates,truckData.fuel.values,startDate,endDate,ANALYSIS_SAMPLE_INTERVAL_SECONDS);// Convert Date objects back to ISO strings for API compatibility\nconst datesAsStrings=mpgResult.dates.map(d=>d.toISOString());return{truck,dates:datesAsStrings,mpg_readings:mpgResult.mpg_values};}// ===== API Functions =====\n/**\n * Fetch MPG history for a single truck.\n * Uses 15-minute sampling interval for high-resolution analysis.\n * \n * For \"upload\" provider, calculates MPG from localStorage data.\n * For \"geotab\" and \"motive\", fetches from backend API.\n */export async function getMpgHistory(sessionId,service,truck,startDate,endDate){// Handle manual upload provider (client-side calculation)\nif(service===\"upload\"){return getMpgHistoryFromUpload(truck,startDate,endDate);}// Handle API providers (backend calculation)\nconst endpoint=`/api/v1/telematics/${service}/get_mpg_history`;const query={truck,start_date:startDate.toISOString(),end_date:endDate.toISOString(),sample_interval_in_seconds:ANALYSIS_SAMPLE_INTERVAL_SECONDS};const data=await apiPost(endpoint,{queries:[query]},sessionId);// Backend returns array, we requested one truck\nreturn data.mpg_histories[0];}/**\n * Generate a PNG timeseries plot for a single truck.\n * Used for quality inspection on the dates page.\n * Requests a large PNG (1320x300) to fill the max container width.\n */export async function getSingleTruckPlot(mpgHistory,treatmentStartDate,treatmentEndDate,sessionId){const endpoint=\"/api/v1/plots/single_truck_timeseries\";const response=await fetch(`${API_URL}${endpoint}`,{method:\"POST\",headers:{\"Content-Type\":\"application/json\",\"X-Session-ID\":sessionId},body:JSON.stringify({data:{mpg_history:mpgHistory,treatment_start_date:treatmentStartDate?.toISOString()??null,treatment_end_date:treatmentEndDate?.toISOString()??null},output:{format:\"png\",width:1320,height:300,max_points:1e4}})});if(!response.ok){throw new Error(`Plot API error: ${response.status}`);}// Convert PNG bytes to base64 data URL\nconst blob=await response.blob();return new Promise((resolve,reject)=>{const reader=new FileReader;reader.onloadend=()=>resolve(reader.result);reader.onerror=reject;reader.readAsDataURL(blob);});}/**\n * Check data quality for a single truck's timeseries.\n * Returns observation counts, variance metrics, and caveats.\n */export async function getQualityCheck(mpgHistory,treatmentStartDate,treatmentEndDate,sessionId){const endpoint=\"/api/v1/quality/check_truck\";return apiPost(endpoint,{mpg_history:mpgHistory,treatment_start_date:treatmentStartDate.toISOString(),treatment_end_date:treatmentEndDate.toISOString()},sessionId);}/**\n * Run the full statistical analysis (Anthos regression).\n * Returns raw API response - use enrichRegressionResults() to add computed aggregates.\n */export async function getImpactEstimate(controlMpgHistories,testMpgHistories,treatmentStartDate,treatmentEndDate,sessionId){const endpoint=\"/api/v1/statistics/impact_estimate\";return apiPost(endpoint,{control_trucks:controlMpgHistories,test_trucks:testMpgHistories,treatment_start_date:treatmentStartDate.toISOString(),treatment_end_date:treatmentEndDate.toISOString()},sessionId);}/**\n * Generate treatment comparison bar chart PNG.\n * Shows before/after averages with scatter overlay.\n */export async function getComparisonPlot(baselineAvgMpg,treatmentAvgMpg,baselineMpgValues,treatmentMpgValues,sessionId){const endpoint=\"/api/v1/plots/treatment_comparison\";const response=await fetch(`${API_URL}${endpoint}`,{method:\"POST\",headers:{\"Content-Type\":\"application/json\",\"X-Session-ID\":sessionId},body:JSON.stringify({data:{baseline_avg_mpg:baselineAvgMpg,treatment_avg_mpg:treatmentAvgMpg,baseline_mpg_values:baselineMpgValues,treatment_mpg_values:treatmentMpgValues},output:{format:\"png\",width:1e3,height:500}})});if(!response.ok){throw new Error(`Comparison plot API error: ${response.status}`);}const blob=await response.blob();return new Promise((resolve,reject)=>{const reader=new FileReader;reader.onloadend=()=>resolve(reader.result);reader.onerror=reject;reader.readAsDataURL(blob);});}/**\n * Generate prediction plot PNG for a single truck.\n * Shows actual MPG with model prediction overlay.\n */export async function getPredictionPlot(mpgHistory,truckAnalysis,regressionResults,treatmentStartDate,treatmentEndDate,sessionId){const endpoint=\"/api/v1/plots/timeseries_with_prediction\";const response=await fetch(`${API_URL}${endpoint}`,{method:\"POST\",headers:{\"Content-Type\":\"application/json\",\"X-Session-ID\":sessionId},body:JSON.stringify({data:{mpg_history:mpgHistory,truck_analysis:truckAnalysis,regression_results:regressionResults,treatment_start_date:treatmentStartDate.toISOString(),treatment_end_date:treatmentEndDate.toISOString()},output:{format:\"png\",width:1e3,height:400,max_points:1e4}})});if(!response.ok){throw new Error(`Prediction plot API error: ${response.status}`);}const blob=await response.blob();return new Promise((resolve,reject)=>{const reader=new FileReader;reader.onloadend=()=>resolve(reader.result);reader.onerror=reject;reader.readAsDataURL(blob);});}/**\n * MCP COMPATIBILITY FOOTER. DO NOT MODIFY.\n * FEROX SYSTEMS 2025\n * @framerDisableUnlink\n */export function withMcp(Component){return Component;}\nexport const __FramerMetadata__ = {\"exports\":{\"getDefaultStudyDates\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"TimeSeriesQualityCheck\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"StatisticalEstimate\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"hasValidMpgData\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getImpactEstimate\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"TruckAnalysis\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"MpgHistory\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getMpgHistory\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"EnrichedRegressionResults\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getQualityCheck\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"AnthosRegressionResults\":{\"type\":\"tsType\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"withMcp\":{\"type\":\"reactHoc\",\"name\":\"withMcp\",\"annotations\":{\"framerContractVersion\":\"1\",\"framerDisableUnlink\":\"\"}},\"ANALYSIS_SAMPLE_INTERVAL_SECONDS\":{\"type\":\"variable\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getPredictionPlot\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getSingleTruckPlot\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"getComparisonPlot\":{\"type\":\"function\",\"annotations\":{\"framerContractVersion\":\"1\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}"],"mappings":"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"}