/*
Copyright 2012-2026 VeloViewer. All Rights Reserved
###V20###
*/
var columns = [
    /*{id:0,title:'Pos',desc:'Position',lngDesc:'Your current position on the segment leaderboard.',width:'auto',class:'ar',field:'r',type:'num',display:'int', hideZeros:0, defOrder: 'asc'},
    {id:1,title:'Pos +/-',desc:'Position change',lngDesc:'The difference in your position on last changed.',width:'auto',class:'ar',field:'lc',type:'num',display:'int', hideZeros:0, defOrder: 'asc'},
    {id:2,title:'Changed',desc:'Last changed',lngDesc:'When your placing changed (when you checked positions).',width:'auto',class:'',field:'drc',type:'date',display:'date', hideZeros:0, defOrder: 'desc'},
    {id:3,title:'Pos<br/>Score',desc:'Position score',lngDesc:'Your position score is based on your position against the total number of athletes to have completed the segment, close to 100 is good, 0 is bad!',width:'auto',class:'ar',field:'s',type:'num',display:'2dp', hideZeros:0, defOrder: 'desc'},
    */
    { id: 4, title: 'Total', desc: 'Total athletes', lngDesc: 'How many athletes have completed the segment.', width: 'auto', class: 'ar', field: 's_tac', type: 'num', display: 'int', hideZeros: 0, defOrder: 'desc' },
    { id: 5, title: 'Type', desc: 'Segment type', lngDesc: 'The activity type of the segment.', width: 'auto', class: '', field: 's_t', type: 'list', display: 'list', hideZeros: 0, defOrder: 'asc' },
    { id: 6, title: 'Name', desc: 'Segment name', lngDesc: 'The segment\'s name.', width: '150px', class: 'clipText', field: 's_sn', type: 'text', display: 'text', hideZeros: 0, defOrder: 'asc' },
    { id: 7, title: 'Tries', desc: 'Tries', lngDesc: 'The number of times you\'ve completed the segment.', width: 'auto', class: 'ar', field: 's_tr', type: 'num', display: 'int', hideZeros: 0, defOrder: 'desc' },
    { id: 8, title: 'City', desc: 'City', lngDesc: 'The closest city to the segment.', width: 'auto', class: '', field: 's_c', type: 'text', display: 'text', maxLen: 15, hideZeros: 0, defOrder: 'asc' },
    { id: 9, title: 'State', desc: 'State', lngDesc: 'The state/county of the segment.', width: 'auto', class: '', field: 's_st', type: 'text', display: 'text', maxLen: 15, hideZeros: 0, defOrder: 'asc' },
    { id: 10, title: 'Dist<br/>' + lrgLenUnit, desc: 'Distance', lngDesc: 'The length of the segment.', width: 'auto', class: '', field: 'd', type: 'num', display: 'vlLen', hideZeros: 0, defOrder: 'desc' },
    { id: 11, title: 'Elapsed<br/>Time', desc: 'Elapsed time', lngDesc: 'The elapsed time (including any stops).', width: 'auto', class: '', field: 'et', type: 'num', display: 'lTime', hideZeros: 0, defOrder: 'asc' },
    //{id:12,title:'Behind<br/>Leader',desc:'Time behind leader',lngDesc:'The amount of time you are behind the leader.',width:'auto',class:'',field:'bl',type:'num',display:'lTime', hideZeros:1, defOrder: 'asc'},
    //{id:13,title:'Behind<br/>Leader %',desc:'% behind leader',lngDesc:'The percentage of time you are behind the leader.',width:'auto',class:'',field:'pbl',type:'num',display:'1dp', hideZeros:1, defOrder: 'asc'},
    { id: 14, title: 'Grade<br/>%', desc: 'Grade %', lngDesc: '', width: 'auto', class: '', field: 's_gr', type: 'num', display: '2dp', hideZeros: 0, defOrder: 'desc' },
    { id: 15, title: 'Max Grade<br/>%', desc: 'Max Grade %', lngDesc: '', width: 'auto', class: '', field: 's_mg', type: 'num', display: '1dp', hideZeros: 0, defOrder: 'desc' },
    { id: 16, title: 'Elv gain<br/>' + smlLenUnit, desc: 'Elevation gain', lngDesc: '', width: 'auto', class: '', field: 's_eg', type: 'num', display: 'sLen', hideZeros: 0, defOrder: 'desc' },
    { id: 17, title: 'Elv change<br/>' + smlLenUnit, desc: 'Elevation change', lngDesc: '', width: 'auto', class: '', field: 's_ed', type: 'num', display: 'sLen', hideZeros: 0, defOrder: 'desc' },
    { id: 18, title: 'Max Elv<br/>' + smlLenUnit, desc: 'Max elevation', lngDesc: '', width: 'auto', class: '', field: 's_eh', type: 'num', display: 'sLen', hideZeros: 0, defOrder: 'desc' },
    { id: 19, title: 'Cat', desc: 'Climb category', lngDesc: '', width: 'auto', class: '', field: 's_cc', type: 'list', display: 'list', hideZeros: 0, defOrder: 'asc' },
    { id: 20, title: 'Speed<br/>' + speedUnit, desc: 'Avg speed', lngDesc: '', width: 'auto', class: '', field: 'as', type: 'num', display: 'speed', hideZeros: 0, defOrder: 'desc' },
    { id: 21, title: 'Pace<br/>' + lrgPaceUnit, desc: 'Avg pace ' + lrgPaceUnit, lngDesc: '', width: 'auto', class: '', field: 'paLrg', type: 'lrgPace', display: 'sTime', hideZeros: 0, defOrder: 'asc' },
    { id: 22, title: 'Pace<br/>' + smlPaceUnit, desc: 'Avg pace ' + smlPaceUnit, lngDesc: '', width: 'auto', class: '', field: 'paSml', type: 'smlPace', display: 'sTime', hideZeros: 0, defOrder: 'asc' },
    { id: 23, title: 'VAM', desc: 'VAM', lngDesc: '', width: 'auto', class: 'ar', field: 'v', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    //{id:24,title:'Leader<br/>VAM',lngDesc:'',desc:'Leader VAM',width:'auto',class:'ar',field:'bv',type:'num',display:'int', hideZeros:1, defOrder: 'desc'},
    { id: 25, title: 'RP', desc: 'Relative Power W/kg', lngDesc: '', width: 'auto', class: 'ar', field: 'rp', type: 'num', display: '2dp', hideZeros: 1, defOrder: 'desc' },
    //{id:26,title:'Leader<br/>RP',desc:'Leader RP W/kg',lngDesc:'',width:'auto',class:'ar',field:'brp',type:'num',display:'2dp', hideZeros:1, defOrder: 'desc'},
    { id: 27, title: 'Activity', desc: 'Activity name', lngDesc: '', width: '150px', class: 'clipText', field: 'a_an', type: 'text', display: 'text', hideZeros: 0, defOrder: 'asc' },
    { id: 28, title: 'When', desc: 'When', lngDesc: '', width: 'auto', class: '', field: 'a_s', type: 'date', display: 'date', hideZeros: 0, defOrder: 'desc' },
    //{id:29,title:'Dist<br/>away<br/>'+lrgLenUnit,desc:'Distance away',lngDesc:'',width:'auto',class:'',field:'startLngLat',type:'geo',lat:'lat',lng:'lng',display:'lLen', hideZeros:0, defOrder: 'asc'},
    //{id:30,title:'Orig',desc:'Original position',lngDesc:'The position of your PR at the time of upload to Strava (only 1-10).',width:'auto',class:'ar',field:'or',type:'num',display:'int', hideZeros:1, defOrder: 'asc'},
    { id: 31, title: 'pVAM', desc: 'Predicted VAM', lngDesc: '', width: 'auto', class: 'ar', field: 'pv', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    { id: 32, title: 'Bearing', desc: 'Bearing', lngDesc: '', width: 'auto', class: 'ar', field: 's_b', type: 'num', display: 'arrow', hideZeros: 0, defOrder: 'asc' },
    { id: 33, title: 'Group<br/>Size', desc: 'Group size', lngDesc: 'How many athletes (including you) in the group for the activity', width: 'auto', class: 'ar', field: 'a_atc', type: 'num', display: 'int', hideZeros: 0, defOrder: 'asc' },
    { id: 34, title: 'Gear', desc: 'Gear', lngDesc: 'Gear (bike or shoes)', width: 'auto', class: 'ar', field: 'a_g', type: 'list', display: 'list', hideZeros: 0, defOrder: 'asc' },
    { id: 108, title: 'Device/App', desc: 'Device/App', lngDesc: 'Device/App used to record the data', width: 'auto', class: '', field: 'a_dv', type: 'list', display: 'list', hideZeros: 0, defOrder: 'asc' },
   { id: 35, title: 'Heart Rate', desc: 'Heart rate', lngDesc: 'Average heart rate', width: 'auto', class: 'ar', field: 'ah', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    { id: 36, title: 'Power (W)', desc: 'Power (W)', lngDesc: 'Average power in Watts', width: 'auto', class: 'ar', field: 'aw', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    { id: 38, title: 'Power<br/>Meter', desc: 'Power meter', lngDesc: 'Has power meter', width: 'auto', class: 'ar', field: 'a_hp', type: 'list', display: 'list', hideZeros: 0, defOrder: 'asc' },
    { id: 37, title: '★', desc: 'Starred', lngDesc: 'Starred', width: 'auto', class: '', field: 'if', type: 'list', display: 'list', hideZeros: 0, defOrder: 'asc' },
    { id: 39, title: 'Cadence', desc: 'Cadence average', lngDesc: 'Average cadence', width: 'auto', class: 'ar', field: 'ac', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    { id: 40, title: 'Max HR', desc: 'Max Heart rate', lngDesc: 'Maximum heart rate', width: 'auto', class: 'ar', field: 'mh', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    { id: 41, title: 'FTP<br/>(W)', desc: 'FTP power (W)', lngDesc: 'Functional Threshold Performance using actual power. Only for efforts > 20 minutes. Power meter only.', width: 'auto', class: 'ar', field: 'pftp', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    { id: 42, title: 'FTP<br/>bpm', desc: 'FTP heart rate', lngDesc: 'Functional Threshold Performance using heart rate. Only for efforts > 20 minutes.', width: 'auto', class: 'ar', field: 'hrftp', type: 'num', display: 'int', hideZeros: 1, defOrder: 'desc' },
    { id: 44, title: 'Segment Id', desc: 'Segment Id', lngDesc: 'Segment id', width: 'auto', class: 'ar', field: 'si', type: 'num', display: 'text', hideZeros: 0, defOrder: 'asc' },
    { id: 104, title: 'Activity Id', desc: 'Activity Id', lngDesc: 'Activity id', width: 'auto', class: 'ar', field: 'ai', type: 'num', display: 'text', hideZeros: 0, defOrder: 'asc' },
    { id: 45, title: 'PR Pos', desc: 'PR Position', lngDesc: 'This effort\'s position compared to all of your other attempts at this segment.', width: 'auto', class: 'ar', field: 'pr', type: 'num', display: 'int', hideZeros: 0, defOrder: 'asc' },
    { id: 46, title: 'PR Pos<br/>Score', desc: 'PR Position score', lngDesc: 'Your PR position score is based on this effort\'s position against the other times you\'ve completed the segment, close to 100 is good, 0 is bad!', width: 'auto', class: 'ar', field: 'prs', type: 'num', display: '2dp', hideZeros: 0, defOrder: 'desc' },
    { id: 51, title: 'Temp<br/>°' + tempUnit, desc: 'Temperature', lngDesc: 'Average temperature for activity', width: 'auto', class: '', field: 'a_tm', type: 'num', display: 'int', hideZeros: 0, defOrder: 'asc' }
];
var chartDefX = 11;
var chartDefY = 10;
var chartDefZ = 7;
var chartDefC = 4;

var chartTypeVal = 0;
// run  : 0,1,2,3,4,5,6,7,8,9,10,11,12,13,21,27,28,29
// ride : 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,23,24,25,26,27,28,29

var segAsyncCount = 0,
    actAsyncCount = 0;

var cpref = 'e';
var mapsRequired = false;
var segsRequired = false;
    
var confCookie = 'ecnf';
var confType = 1;
var defColOrder = "0,1,2,30,3,4,5,6,37,45,7,46,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,31,25,26,35,40,39,36,38,41,42,27,34,108,28,33,51,32,45,46,44,104".split(',');

function getConfigs() {
    allCols = "0,1,2,30,3,4,5,6,37,45,7,46,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,31,25,26,35,40,39,36,38,41,42,27,34,108,28,33,51,32,45,46,44,104";
    c = [{
        "id": "1",
        "athleteId": "-1",
        "type": "1",
        "name": "All",
        "colOrder": allCols,
        "dataOrder": "7:1",
        "editable": false,
        "temp": false,
        "filters": ""
    }];
    curConfig = getCookie(confCookie);
    if (typeof(curConfig) == 'undefined') {
        curConfig = 1;
    }

    if (window.location.search != '' && (getParameterByName('f') != '' || getParameterByName('o') != '')) {
        var filters = getParameterByName('f');
        var order = getParameterByName('o');
        customConfig = c.length;
        c.push({
            "id": "2",
            "athleteId": "-1",
            "type": "0",
            "name": "Custom",
            "colOrder": allCols,
            "dataOrder": (order == '' ? "7:1" : order),
            "editable": false,
            "temp": false,
            "filters": filters
        });
        curConfig = 2;
    }

    if (window.location.search != '' && (getParameterByName('c') != '')) {
        var co = getParameterByName('c').split(',').map(function(d) {
            return +d
        });
        if (co.length > 2) {
            chartTypeVal = co[0];
            chartDefX = co[1];
            chartDefY = co[2];
            chartDefZ = (co.length > 3 ? co[3] : 0);
            chartDefC = (co.length > 4 ? co[4] : 0);
        }
    }

    for (i = 0; i < c.length; i++) {
        var ta = c[i].colOrder.split(',');
        c[i].colDisp = Array(defColOrder.length + 1).join('.').split('').map(function(d, j) {
            return (j < ta.length ? 0 : 7)
        }).join();
        c[i].colOrder += ',' + defColOrder.filter(function(d) {
            return ta.indexOf(d) == -1
        }).join();
    }
}
getConfigs();

function localInit() {
    if (segCacheReady && actCacheReady && segAsyncCount + actAsyncCount == 0) {
        if (!s_s) {
            d3.selectAll('.tab-content').html('<p style="margin-bottom:10em"><b>Important note:</b> To conform with Strava\'s API terms and conditions, this tab is <a href="' + s_sBlogLink + '" target="_blank">only available to Strava Subscribers</a>. VeloViewer users can get a <a href="https://promo.strava.com/veloviewer/" target="_blank">60 day free Strava Premium trial here</a>.</p>');
            return;
        }
        if (typeof(cacheSeg) !== 'undefined' && typeof(cacheAct) !== 'undefined') {
            if ( /*cacheSeg.length > 0 &&*/ cacheAct.length > 0) {
                var actIds = cacheAct.reduce(function(acc, val, i) {
                    acc[val.ai] = 1
                    return acc;
                }, {});
                var segIds = cacheSeg.reduce(function(acc, val, i) {
                    acc[val.si] = 1
                    return acc;
                }, {});
                cacheAct = null;
                cacheSeg = null;
                a = [];
                for (var eff in teffs) {
                	var d = teffs[eff];
                    if (d.length > 0 && actIds[d[0].ai]) {
                        a = a.concat(d.filter(function(e) {
                            return segIds[e.si] //&& typeof(tsegs[e.si].f) === 'undefined'
                        }));
                    }
                    teffs[eff] = null;
                }
                teffs = null;
                a = /*d3.merge(d3.values(teffs))
                    .filter(function(d) {
                        return actIds.indexOf(d.ai) > -1 && segIds.indexOf(d.si) > -1 && typeof(tsegs[d.si].f) === 'undefined'
                            //return typeof(tacts[d.ai]) !== 'undefined' && typeof(tsegs[d.si]) !== 'undefined' && typeof(tsegs[d.si].f) === 'undefined'
                    })*/
                    a.map(function(d) {
                        /*for (var att in tacts[d.ai]) {
                            d['a_' + att] = tacts[d.ai][att];
                        }*/
                        /*for (var att in tsegs[d.si]) {
                            d['s_' + att] = tsegs[d.si][att];
                        }*/

                        d.a_an = tacts[d.ai]['an'];
                        d.a_as = tacts[d.ai]['as'];
                        d.a_atc = tacts[d.ai]['atc'];
                        d.a_g = tacts[d.ai]['g'];
                        d.a_hp = tacts[d.ai]['hp'];
                        d.a_s = tacts[d.ai]['s'];
                        d.a_tm = tacts[d.ai]['tm'];
                        d.a_dv = tacts[d.ai]['dv'];

                        d.s_b = tsegs[d.si]['b'];
                        d.s_c = tsegs[d.si]['c'];
                        d.s_cc = tsegs[d.si]['cc'];
                        d.s_cmc = tsegs[d.si]['cmc'];
                        d.s_ed = tsegs[d.si]['ed'];
                        d.s_eg = tsegs[d.si]['eg'];
                        d.s_eh = tsegs[d.si]['eh'];
                        d.s_gr = tsegs[d.si]['gr'];
                        d.s_mg = tsegs[d.si]['mg'];
                        d.s_st = tsegs[d.si]['st'];
                        d.s_sn = tsegs[d.si]['sn'];
                        d.s_t = tsegs[d.si]['t'];
                        d.s_tac = tsegs[d.si]['tac'];
                        d.s_tr = tsegs[d.si]['tr'];
                        d.if = tsegs[d.si]['if'];

                        d.as = d.d / d.et;
                        d.pa = 1 / d.as;
                        d.v = 0;
                        d.rp = 0;
                        if (d.s_cc != 'n/a') {
                            d.s_gf = 2 + d.s_gr / 10;

                            d.v = d.s_ed * 3600 / d.et;
                            d.rp = d.v / (d.s_gf * 100);
                        }
                        if (typeof(d.aw) !== 'undefined' && /*d.hp == 1 &&*/ d.et >= 60 * 20 && d.aw != 0) {
                            d.pftp = d.aw * Math.min(1, (0.05 / 4) * ((d.et / 60) - 20) / 10 + 0.95);
                        } else {
                            d.pftp = 0;
                        }
                        if (typeof(d.ah) !== 'undefined' && d.et >= 60 * 20 && d.ah > 0) {
                            d.hrftp = d.ah * Math.min(1, (0.05 / 4) * ((d.et / 60) - 20) / 10 + 0.95);
                        } else {
                            d.hrftp = 0;
                        }
                        return d
                    });
                tsegs = null;
                tacts = null;
                a.sort(function(a, b) {
                    return a.si == b.si ? b.pr - a.pr : b.si - a.si
                });
                a.forEach(function(d, i) {
                    d.seq = i;
                });
                setConfig();
                init();
            } else {
                if (hasLocalStorage) {
                    localStorage.clear();
                }
                alert('Your data doesn\'t appear to be complete! Make sure you\'ve completed at least one, full sync on the update page. If you think all your data is already synced then try refreshing the page. Also make sure that your activities in Strava contain at least one segment.');
            }
        } else {
            if (hasLocalStorage) {
                localStorage.clear();
            }
            alert('Oh dear, something\'s not gone right. Try refreshing the page (Ctrl+F5 to clear your cache might help) and see if it helps. If you keep seeing this message then let me know.');
        }
    }
}

if (isFree) {
    d3.select('#tourInfo')
        .style('display', null)
        .classed('alert alert-info', true)
        .html('<h4>VeloViewer Tour Notes</h4><p style="margin-top:8px;font-weight:bold">Restricted to the efforts of your 25 activies and 250 segments for free users. <a href="/update">Upgrade to PRO</a> to see your entire Strava history of segment efforts.</p><p>Stats for every single attempt (effort) you\'ve had on all of your segments.  Great for checking your progress over time and also for checking out your estimated FTP values.</p><p><b>Go to your Update page at any time to <a href="/update">Upgrade to PRO</a> to view your entire Strava history and segments in VeloViewer (and to hide these notes).</b></p>');
}
