<commit_before>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        console.log('positionCurrent.hng ',positionCurrent.hng,positionCurrent);
        console.log( (360 - phase | 0) + "°");

        /*
        if(worldAdjustRotation==null != worldAdjustRotation !=0)
        {
            worldAdjustRotation = positionCurrent.hng;
            $('#pointers').attr('rotation','0 '+positionCurrent.hng+' 0');
            alert('Ajuste: '+parseInt(positionCurrent.hng));
        }
        */

        $('#pointers').attr('rotation','0 15 0');

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);
    /*
    window.addEventListener("deviceorientation", function(event)
    {

        var xValue      = Math.round(event.gamma);
        var yValue      = Math.round(event.beta);
        var rotation    = Math.round(event.alpha);

        //$('#cameraControl').attr('rotation' , '0 '+yValue+' 0');

        $('.orientation').html('xValue :'+xValue + '
yValue :'+yValue+ '
rotation :'+rotation)

    }, true)
    */

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 100000;
MAP_HEIGHT          = 100000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 5000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }
            console.log(difCoordenads)

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var cylinder	= document.createElement('a-cylinder');
        cylinder.setAttribute("position"    , '0 0 -10');
        cylinder.setAttribute("radius"	    , "0.5");
        cylinder.setAttribute("height"      , "1.5");
        cylinder.setAttribute("color"       , "#ff0000");

        scene.appendChild(cylinder);
    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<commit_msg>compass<commit_after>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        console.log('positionCurrent.hng ',positionCurrent.hng,positionCurrent);
        console.log( (360 - phase | 0) + "°");

        /*
        if(worldAdjustRotation==null != worldAdjustRotation !=0)
        {
            worldAdjustRotation = positionCurrent.hng;
            $('#pointers').attr('rotation','0 '+positionCurrent.hng+' 0');
            alert('Ajuste: '+parseInt(positionCurrent.hng));
        }
        */

        //$('#pointers').attr('rotation','0 15 0');

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);
    /*
    window.addEventListener("deviceorientation", function(event)
    {

        var xValue      = Math.round(event.gamma);
        var yValue      = Math.round(event.beta);
        var rotation    = Math.round(event.alpha);

        //$('#cameraControl').attr('rotation' , '0 '+yValue+' 0');

        $('.orientation').html('xValue :'+xValue + '
yValue :'+yValue+ '
rotation :'+rotation)

    }, true)
    */

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 100000;
MAP_HEIGHT          = 100000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 5000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }
            console.log(difCoordenads)

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var cylinder	= document.createElement('a-cylinder');
        cylinder.setAttribute("position"    , '0 0 -10');
        cylinder.setAttribute("radius"	    , "0.5");
        cylinder.setAttribute("height"      , "1.5");
        cylinder.setAttribute("color"       , "#ff0000");

        scene.appendChild(cylinder);
    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<|endoftext|>


<commit_before>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        console.log('positionCurrent.hng ',positionCurrent.hng,positionCurrent);
        console.log( (360 - phase | 0) + "°");

        /*
        if(worldAdjustRotation==null != worldAdjustRotation !=0)
        {
            worldAdjustRotation = positionCurrent.hng;
            $('#pointers').attr('rotation','0 '+positionCurrent.hng+' 0');
            alert('Ajuste: '+parseInt(positionCurrent.hng));
        }
        */

        //$('#pointers').attr('rotation','0 65 0');

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);
    /*
    window.addEventListener("deviceorientation", function(event)
    {

        var xValue      = Math.round(event.gamma);
        var yValue      = Math.round(event.beta);
        var rotation    = Math.round(event.alpha);

        //$('#cameraControl').attr('rotation' , '0 '+yValue+' 0');

        $('.orientation').html('xValue :'+xValue + '
yValue :'+yValue+ '
rotation :'+rotation)

    }, true)
    */

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 1000000;
MAP_HEIGHT          = 1000000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2988171,
            lng: -99.1117088,
            info:{
                title: 'Biker Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 1000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var cylinder	= document.createElement('a-cylinder');
        cylinder.setAttribute("position"    , '0 0 -10');
        cylinder.setAttribute("radius"	    , "0.5");
        cylinder.setAttribute("height"      , "1.5");
        cylinder.setAttribute("color"       , "#ff0000");

        scene.appendChild(cylinder);
    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<commit_msg>compass<commit_after>// check for Geolocation support
if (navigator.geolocation)
{

    console.log('Geolocation is supported!');
}
else
{
    alert('Geolocation is not supported for this Browser/OS version yet.');
}

// our current position
var worldAdjustRotation = null;
var positionHng;
var defaultOrientation;
var positionCurrent = {
    lat: null,
    lng: null,
    hng: null
};

function getBrowserOrientation() {
    var orientation;
    if (screen.orientation && screen.orientation.type) {
        orientation = screen.orientation.type;
    } else {
        orientation = screen.orientation ||
            screen.mozOrientation ||
            screen.msOrientation;
    }

    /*
     'portait-primary':      for (screen width < screen height, e.g. phone, phablet, small tablet)
     device is in 'normal' orientation
     for (screen width > screen height, e.g. large tablet, laptop)
     device has been turned 90deg clockwise from normal

     'portait-secondary':    for (screen width < screen height)
     device has been turned 180deg from normal
     for (screen width > screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal

     'landscape-primary':    for (screen width < screen height)
     device has been turned 90deg clockwise from normal
     for (screen width > screen height)
     device is in 'normal' orientation

     'landscape-secondary':  for (screen width < screen height)
     device has been turned 90deg anti-clockwise (or 270deg clockwise) from normal
     for (screen width > screen height)
     device has been turned 180deg from normal
     */

    return orientation;
}

function onHeadingChange(event) {
    var heading = event.alpha;

    if (typeof event.webkitCompassHeading !== "undefined") {
        heading = event.webkitCompassHeading; //iOS non-standard
    }

    var orientation = getBrowserOrientation();

    if (typeof heading !== "undefined" && heading !== null)
    {
        // && typeof orientation !== "undefined") {
        // we have a browser that reports device heading and orientation

        // what adjustment we have to add to rotation to allow for current device orientation
        var adjustment = 0;
        if (defaultOrientation === "landscape") {
            adjustment -= 90;
        }

        if (typeof orientation !== "undefined") {
            var currentOrientation = orientation.split("-");

            if (defaultOrientation !== currentOrientation[0])
            {
                if (defaultOrientation === "landscape")
                {
                    adjustment -= 270;
                }
                else
                {
                    adjustment -= 90;
                }
            }

            if (currentOrientation[1] === "secondary")
            {
                adjustment -= 180;
            }
        }

        positionCurrent.hng = heading + adjustment;

        var phase = positionCurrent.hng < 0 ? 360 + positionCurrent.hng : positionCurrent.hng;
        //positionHng.textContent = (360 - phase | 0) + "°";

        console.log('positionCurrent.hng ',positionCurrent.hng,positionCurrent);
        console.log( (360 - phase | 0) + "°");

        /*
        if(worldAdjustRotation==null != worldAdjustRotation !=0)
        {
            worldAdjustRotation = positionCurrent.hng;
            $('#pointers').attr('rotation','0 '+positionCurrent.hng+' 0');
            alert('Ajuste: '+parseInt(positionCurrent.hng));
        }
        */

        //$('#pointers').attr('rotation','0 65 0');

        $('.brujula').html(parseFloat(positionCurrent.hng).toFixed(2)+ "°")

        /*
        // apply rotation to compass rose
        if (typeof rose.style.transform !== "undefined") {
            rose.style.transform = "rotateZ(" + positionCurrent.hng + "deg)";
        } else if (typeof rose.style.webkitTransform !== "undefined") {
            rose.style.webkitTransform = "rotateZ(" + positionCurrent.hng + "deg)";
        }
        */
    }
    else
    {
        // device can't show heading

        positionHng  = "n/a";
        console.log('brujula no disponible');
    }
}

if (window.DeviceOrientationEvent) {

    if (screen.width > screen.height)
    {
        defaultOrientation = "landscape";
    }
    else
    {
        defaultOrientation = "portrait";
    }

    window.addEventListener("deviceorientation", onHeadingChange);
    /*
    window.addEventListener("deviceorientation", function(event)
    {

        var xValue      = Math.round(event.gamma);
        var yValue      = Math.round(event.beta);
        var rotation    = Math.round(event.alpha);

        //$('#cameraControl').attr('rotation' , '0 '+yValue+' 0');

        $('.orientation').html('xValue :'+xValue + '
yValue :'+yValue+ '
rotation :'+rotation)

    }, true)
    */

} else {
    alert("Sorry, your browser doesn't support Device Orientation");
}

MAP_WIDTH           = 1000000;
MAP_HEIGHT          = 1000000;
var store_current   = null;

function convert(lat, lon){
    var y = ((-1 * lat) + 90) * (MAP_HEIGHT / 180);
    var x = (lon + 180) * (MAP_WIDTH / 360);
    return {x:x,y:y};
}

window.onload = function()
{
    var startPos;
    var stores =
    [
        {
            lat: 19.4375921,
            lng: -99.2099433,
            info:{
                title: 'Superama Los Morales',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.4477107,
            lng: -99.2171927,
            info:{
                title: 'Sam\'s Club Toreo',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'sams'
            }
        },
        {
            lat: 19.4373714,
            lng: -99.2056145,
            info:{
                title: 'Superama Polanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'superama'
            }
        },
        {
            lat: 19.2973321,
            lng: -99.1065446,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2989663,
            lng: -99.1059896,
            info:{
                title: 'Bodega Aurrera Hueso',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2982219,
            lng: -99.1143161,
            info:{
                title: 'Audi Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat: 19.2988171,
            lng: -99.1117088,
            info:{
                title: 'Biker Coapa',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },
        {
            lat:19.2969037,
            lng: -99.1119386,
            info:{
                title: 'IIM',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'ba'
            }
        },

    ];

    $('.cerrar').click(function()
    {
        $('.info').hide();
    });

    $('.debug').click(function()
    {
        if($('#tripmeter').is(':visible'))
        {
            $('#tripmeter').hide();
        }
        else
        {
            $('#tripmeter').show();
        }
    });

    navigator.geolocation.getCurrentPosition(
        function(position)
        {
            startPos = position;
            document.getElementById('startLat').innerHTML = startPos.coords.latitude;
            document.getElementById('startLon').innerHTML = startPos.coords.longitude;

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[0].lat,stores[0].lng);
            var dif         =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            $('#superama').attr('position',dif.x+' 0.5 '+dif.y);

            var convSams    = convert(stores[1].lat,stores[1].lng);
            var difSams     =
            {
                x: convStart.x - convSams.x,
                y: convStart.y - convSams.y
            }

            $('#sams').attr('position',difSams.x+' 0.5 '+difSams.y);
            $('#sams').attr('show-info', JSON.stringify(stores[1].info));

            var convSup    = convert(stores[2].lat,stores[2].lng);
            var difSup     =
            {
                x: convStart.x - convSup.x,
                y: convStart.y - convSup.y
            }
            $('#supPol').attr('position',difSup.x+' 0.5 '+difSup.y);

            var offset = 10000;
            var difCoordenads = {
                x: (startPos.coords.latitude     - stores[0].lat)*offset,
                y: (startPos.coords.longitude    - stores[0].lng)*offset
            }

            $('#sams').attr('position',difCoordenads.x+' 0.5 '+difCoordenads.y);
            console.log(dif,difCoordenads)

            generatePin(startPos)

        },
        function(error)
        {
            alert('Error occurred. Error code: ' + error.code);
            // error.code can be:
            //   0: unknown error
            //   1: permission denied
            //   2: position unavailable (error response from locaton provider)
            //   3: timed out
        });

    navigator.geolocation.watchPosition(
        function(position)
        {
            console.log('store_current ',store_current);
            document.getElementById('currentLat').innerHTML = position.coords.latitude;
            document.getElementById('currentLon').innerHTML = position.coords.longitude;

            $('.stores').html('');
            for(var s in stores)
            {
                $('.stores').append('
Distance to '+stores[s].info.title+':
 '+calculateDistance(stores[s].lat, stores[s].lng,position.coords.latitude, position.coords.longitude)+' m
')
            }

            if(store_current!=null)
            {
                $('.txt.dist').show();
                $('.txt.dist').html(this.calculateDistance(store_current.lat, store_current.lng,position.coords.latitude, position.coords.longitude)+'m');
            }

        });

    function generatePin(startPos)
    {
        var offset  = 20000;
        var scene   = document.getElementById('pointers');

        for(var s in stores)
        {

            var convStart   = convert(startPos.coords.latitude,startPos.coords.longitude);
            var conv        = convert(stores[s].lat,stores[s].lng);
            var difCoordenads =
            {
                x: convStart.x - conv.x,
                y: convStart.y - conv.y
            }

            difCoordenads =
            {
                x: (startPos.coords.latitude     - stores[s].lat)*offset,
                y: (startPos.coords.longitude    - stores[s].lng)*offset
            }

            var color = '#123123';
            if(stores[s].info.title == 'IIM')
            {
                color = '#ff0000';
            }

            if(stores[s].info.title == 'Audi Coapa')
            {
                color = '#00ff00';
            }

            var box	= document.createElement('a-box');
            box.setAttribute("position"	, difCoordenads.x+' 0.5 '+difCoordenads.y);
            box.setAttribute("rotation"	, "0 45 0");
            box.setAttribute("show-info", JSON.stringify(stores[s]));
            box.setAttribute("color"    , color);
            //box.setAttribute("look-at"	, "[camera]");

            console.log('position' , difCoordenads.x+' 0.5 '+difCoordenads.y)

            scene.appendChild(box);
        }

        var cylinder	= document.createElement('a-cylinder');
        cylinder.setAttribute("position"    , '0 0 -10');
        cylinder.setAttribute("radius"	    , "0.5");
        cylinder.setAttribute("height"      , "1.5");
        cylinder.setAttribute("color"       , "#ff0000");

        scene.appendChild(cylinder);
    }
};

function calculateDistance(lat1, lon1, lat2, lon2)
{
    var R = 6371 * 1000; // m
    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
            Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
            Math.sin(dLon / 2) * Math.sin(dLon / 2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = R * c;
    return d;
}

Number.prototype.toRad = function()
{
    return this * Math.PI / 180;
}
<|endoftext|>


<commit_before>
function updateOnResize() {
  var width = demoplayer.videojs.videoWidth();
  var current = document.getElementById(width);
  var oldactive = document.getElementsByClassName("range-info active");
  for (var i = 0; i < oldactive.length; i++) {
    oldactive[i].setAttribute("class","range-info");
  }
  current.setAttribute("class","range-info active");
}
function requestResolution(btn) {
  console.log("requestResolution() ",btn.id);
  document.getElementById("checkbox").checked = false;
  for (var i = 0; i < qualityLevels.length; i++) {
      qualityLevels[i].enabled = (Number(btn.id) == qualityLevels[i].width);
  }
}
function requestAuto(auto) {
  console.log("requestAuto() ",auto.checked);
  if(auto.checked) {
    for (var i = 0; i < qualityLevels.length; i++) {
        qualityLevels[i].enabled = true;
    }
  }
}

function changeOfResolution() {
  for (var i = 0; i < qualityLevels.length; i++) {
    var res = document.getElementById(qualityLevels[i].width);
    if (i == qualityLevels.selectedIndex)
        res.setAttribute("class","range-info second-hover");
    else
        res.setAttribute("class","range-info");
  }
}

function setProfile(profile) {
  var elements = document.getElementsByClassName('range-info');
  var i = elements.length;

    while(i--) {
      console.log(elements[i].getElementsByClassName(profile.value).length);
        if(elements[i].getElementsByClassName(profile.value).length > 0)
          elements[i].setAttribute("class","range-info");
        else
          elements[i].setAttribute("class","range-info out-of-range");

    }
  demoplayer.source("hd_trim2", { sourceTypes: ['hls'], transformation: {streaming_profile: profile.value } });
}

var cld = cloudinary.Cloudinary.new({ cloud_name: 'hadar' });

var adaptive = document.getElementById("adaptive");
document.getElementById("demo-adaptive-player").addEventListener('resize',updateOnResize, false);

var demoplayer = cld.videoPlayer('demo-adaptive-player');

var qualityLevels = demoplayer.videojs.qualityLevels();
qualityLevels.on('change', changeOfResolution);
qualityLevels.on('addqualitylevel', function(event) { console.log(event.qualityLevel.width); });

demoplayer.source('hd_trim2',{ sourceTypes: ['hls'],
                              transformation: {streaming_profile: 'hd' } });

function updateOnEvent(eventStr) {
  var list = document.getElementById('events-list');
  var entry = document.createElement('li');
  if (eventStr.includes("timeplayed"))
      entry.className = "orange";
  entry.appendChild(document.createTextNode(eventStr));
  list.insertBefore(entry,list.firstChild);
  list.scrollTop = list.scrollHeight;
}

function checkTime(i) {
        return (i < 10) ? "0" + i : i;
    }

function startTime() {
        var today = new Date(),
            h = checkTime(today.getHours()),
            m = checkTime(today.getMinutes()),
            s = checkTime(today.getSeconds());
        return (h + ":" + m + ":" + s);
}

var eventplayer = cld.videoPlayer('demo-events-player', { playedEventTimes: [3, 10] });

var eventTypes = ['play', 'pause', 'volumechange', 'mute', 'unmute', 'fullscreenchange',
      'seek', 'sourcechanged', 'timeplayed', 'percentsplayed', 'ended'];

eventTypes.forEach(function(eventType) {
      eventplayer.on(eventType, function(event) {
        var eventStr = startTime() + " " + eventType;
        if (event.eventData) {
          eventStr = eventStr + ": " + JSON.stringify(event.eventData)
        }
        updateOnEvent(eventStr);
      })
    });

 eventplayer.source('hls_30s_test',{ sourceTypes: ['hls'],
                              transformation: {streaming_profile: 'hd' } });

function playMe(btn) {
    var val = parseInt(btn.value);
    plistplayer.playlist().playAtIndex(val);
  }

  function updateOnSrc() {
    var plist = plistplayer.playlist();
    var playing = plist.currentIndex();
    var loop = plist.length();
    for(var i=0; i<loop; i++) {
      var label = "plist"+i;
      var btn = document.getElementById(label);
      if(i == playing)
        btn.setAttribute("class", "active");
      else
        btn.setAttribute("class", " ");
  }
  console.log("updateOnSrc", playing, loop);
}
var plistplayer = cld.videoPlayer('demo-playlist-player');
plistplayer.on('sourcechanged', updateOnSrc);
plistplayer.playlist(
  [{ publicId: 'game2', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }},
   { publicId: 'hls_30s_test', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }},
   { publicId: 'hd_trim2', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }},
   { publicId: 'Homepage_2', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }}],
   { autoAdvance: 0, repeat: true });

 plistplayer.source('game2',{ sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' } });

var recplayer = cld.videoPlayer('demo-recommendation-player',{ autoShowRecommendations: true });

var source1 = { publicId: 'Homepage_2', info: { title: 'Kid Play', subtitle: 'A preview' } };
var source2 = { publicId: 'game2', info: { title: 'Game', subtitle: 'A game ad' } };
var source3 = { publicId: 'hd_trim2', info: { title: 'Race', subtitle: 'Volve Ocean Race' } };
var source4 = { publicId: 'hls_30s_test', info: { title: 'NBA', subtitle: 'A game' } };
var source5 = { publicId: 'oceans', info: { title: 'Oceans', subtitle: 'A movie about oceans' } };
source1.recommendations = [source2, source3, source4, source5];
source2.recommendations = [source3];
source3.recommendations = [source4];
source4.recommendations = [source5];
source5.recommendations = [source2, source3, source4, source1];
recplayer.source(source1);

<commit_msg>Update draft.js<commit_after>
function updateOnResize() {
  var width = demoplayer.videojs.videoWidth();
  var current = document.getElementById(width);
  var oldactive = document.getElementsByClassName("range-info active");
  for (var i = 0; i < oldactive.length; i++) {
    oldactive[i].setAttribute("class","range-info");
  }
  current.setAttribute("class","range-info active");
}
function requestResolution(btn) {
  console.log("requestResolution() ",btn.id);
  document.getElementById("checkbox").checked = false;
  for (var i = 0; i < qualityLevels.length; i++) {
      qualityLevels[i].enabled = (Number(btn.id) == qualityLevels[i].width);
  }
}
function requestAuto(auto) {
  console.log("requestAuto() ",auto.checked);
  if(auto.checked) {
    for (var i = 0; i < qualityLevels.length; i++) {
        qualityLevels[i].enabled = true;
    }
  }
}

function changeOfResolution() {
  var index = qualityLevels.selectedIndex;
  var res = document.getElementById(qualityLevels[index].width);
  res.setAttribute("class","range-info second-hover");
}

function setProfile(profile) {
  var elements = document.getElementsByClassName('range-info');
  var i = elements.length;

    while(i--) {
      console.log(elements[i].getElementsByClassName(profile.value).length);
        if(elements[i].getElementsByClassName(profile.value).length > 0)
          elements[i].setAttribute("class","range-info");
        else
          elements[i].setAttribute("class","range-info out-of-range");

    }
  demoplayer.source("hd_trim2", { sourceTypes: ['hls'], transformation: {streaming_profile: profile.value } });
}

var cld = cloudinary.Cloudinary.new({ cloud_name: 'hadar' });

var adaptive = document.getElementById("adaptive");
document.getElementById("demo-adaptive-player").addEventListener('resize',updateOnResize, false);

var demoplayer = cld.videoPlayer('demo-adaptive-player');

var qualityLevels = demoplayer.videojs.qualityLevels();
qualityLevels.on('change', changeOfResolution);
qualityLevels.on('addqualitylevel', function(event) { console.log(event.qualityLevel.width); });

demoplayer.source('hd_trim2',{ sourceTypes: ['hls'],
                              transformation: {streaming_profile: 'hd' } });

function updateOnEvent(eventStr) {
  var list = document.getElementById('events-list');
  var entry = document.createElement('li');
  if (eventStr.includes("timeplayed"))
      entry.className = "orange";
  entry.appendChild(document.createTextNode(eventStr));
  list.insertBefore(entry,list.firstChild);
  list.scrollTop = list.scrollHeight;
}

function checkTime(i) {
        return (i < 10) ? "0" + i : i;
    }

function startTime() {
        var today = new Date(),
            h = checkTime(today.getHours()),
            m = checkTime(today.getMinutes()),
            s = checkTime(today.getSeconds());
        return (h + ":" + m + ":" + s);
}

var eventplayer = cld.videoPlayer('demo-events-player', { playedEventTimes: [3, 10] });

var eventTypes = ['play', 'pause', 'volumechange', 'mute', 'unmute', 'fullscreenchange',
      'seek', 'sourcechanged', 'timeplayed', 'percentsplayed', 'ended'];

eventTypes.forEach(function(eventType) {
      eventplayer.on(eventType, function(event) {
        var eventStr = startTime() + " " + eventType;
        if (event.eventData) {
          eventStr = eventStr + ": " + JSON.stringify(event.eventData)
        }
        updateOnEvent(eventStr);
      })
    });

 eventplayer.source('hls_30s_test',{ sourceTypes: ['hls'],
                              transformation: {streaming_profile: 'hd' } });

function playMe(btn) {
    var val = parseInt(btn.value);
    plistplayer.playlist().playAtIndex(val);
  }

  function updateOnSrc() {
    var plist = plistplayer.playlist();
    var playing = plist.currentIndex();
    var loop = plist.length();
    for(var i=0; i<loop; i++) {
      var label = "plist"+i;
      var btn = document.getElementById(label);
      if(i == playing)
        btn.setAttribute("class", "active");
      else
        btn.setAttribute("class", " ");
  }
  console.log("updateOnSrc", playing, loop);
}
var plistplayer = cld.videoPlayer('demo-playlist-player');
plistplayer.on('sourcechanged', updateOnSrc);
plistplayer.playlist(
  [{ publicId: 'game2', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }},
   { publicId: 'hls_30s_test', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }},
   { publicId: 'hd_trim2', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }},
   { publicId: 'Homepage_2', sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' }}],
   { autoAdvance: 0, repeat: true });

 plistplayer.source('game2',{ sourceTypes: ['dash'], transformation: {streaming_profile: 'hd' } });

var recplayer = cld.videoPlayer('demo-recommendation-player',{ autoShowRecommendations: true });

var source1 = { publicId: 'Homepage_2', info: { title: 'Kid Play', subtitle: 'A preview' } };
var source2 = { publicId: 'game2', info: { title: 'Game', subtitle: 'A game ad' } };
var source3 = { publicId: 'hd_trim2', info: { title: 'Race', subtitle: 'Volve Ocean Race' } };
var source4 = { publicId: 'hls_30s_test', info: { title: 'NBA', subtitle: 'A game' } };
var source5 = { publicId: 'oceans', info: { title: 'Oceans', subtitle: 'A movie about oceans' } };
source1.recommendations = [source2, source3, source4, source5];
source2.recommendations = [source3];
source3.recommendations = [source4];
source4.recommendations = [source5];
source5.recommendations = [source2, source3, source4, source1];
recplayer.source(source1);

<|endoftext|>


<commit_before>/**
 * kdtree
 *
 * Is a modified and google closure adapted kdtree implementation
 * of https://github.com/ubilabs/kd-tree-javascript.
 *
 * @author Andrey Antukh <niwi@niwi.nz>, 2016
 * @author Mircea Pricop <pricop@ubilabs.net>, 2012
 * @author Martin Kleppe <kleppe@ubilabs.net>, 2012
 * @author Ubilabs http://ubilabs.net, 2012
 * @license MIT License <https://opensource.org/licenses/MIT>
 */

goog.provide("kdtree.core");
goog.provide("kdtree.core.KDTree");

goog.require("kdtree.heap");
goog.require("goog.array");
goog.require("goog.asserts");

goog.scope(function() {
  "use strict";

  const assert = goog.asserts.assert;
  const assertNumber = goog.asserts.assertNumber;
  const every = goog.array.every;

  class Node {
    constructor(obj, dimension, parent) {
      this.obj = obj;
      this.left = null;
      this.right = null;
      this.parent = parent;
      this.dimension = dimension;
    }
  }

  function precision(v) {
    return parseFloat(v.toFixed(6));
  }

  function buildTree(points, depth, parent, dimensions) {
    const dim = depth % dimensions;

    if (points.length === 0) {
      return null;
    }

    if (points.length === 1) {
      return new Node(points[0], dim, parent);
    }

    points.sort((a, b) => {
      return a[dim] - b[dim];
    });

    const median = Math.floor(points.length / 2);
    const node = new Node(points[median], dim, parent);
    node.left = buildTree(points.slice(0, median), depth + 1, node, dimensions);
    node.right = buildTree(points.slice(median + 1), depth + 1, node, dimensions);

    return node;
  }

  function findMin(node, dim) {
    let dimension, own, left, right, min;

    if (node === null) {
      return null;
    }

    if (node.dimension === dim) {
      if (node.left !== null) {
        return findMin(node.left, dim);
      }
      return node;
    }

    own = node.obj[dim];
    left = findMin(node.left, dim);
    right = findMin(node.right, dim);
    min = node;

    if (left !== null && left.obj[dim] < own) {
      min = left;
    }
    if (right !== null && right.obj[dim] < min.obj[dim]) {
      min = right;
    }
    return min;
  }

  function innerSearch(point, node, parent) {
    if (node === null) {
      return parent;
    }

    if (point[dim] < node.obj[dim]) {
      return innerSearch(point, node.left, node);
    } else {
      return innerSearch(point, node.right, node);
    }
  }

  function nodeSearch(point, node) {
    if (node === null) {
      return null;
    }

    if (node.obj === point) {
      return node;
    }

    if (point[node.dimension] < node.obj[node.dimension]) {
      return nodeSearch(point, node.left);
    } else {
      return nodeSearch(point, node.right);
    }
  }

  class KDTree {
    constructor(points, metric, dimensions) {
      assert(points.length !== 0);
      assertNumber(dimensions);

      this.root = buildTree(points, 0, null, dimensions);
      this.metric = metric;
      this.dimensions = dimensions;
    }

    insert(point) {
      const insertPosition = innerSearch(point, this.root, null);

      if (insertPosition === null) {
        this.root = new Node(point, 0, null);
        return;
      }

      const newNode = new Node(point,
                               (insertPosition.dimension + 1) % this.dimensions,
                               insertPosition);

      const dimension = insertPosition.dimension;
      if (point[dimension] < insertPosition.obj[dimension]) {
        insertPosition.left = newNode;
      } else {
        insertPosition.right = newNode;
      }
    }

    remove(point) {
      const node = nodeSearch(point, this.root);
      if (node === null) {
        return;
      }

      if (node.left === null && node.right === null) {
        if (node.parent === null) {
          this.root = null;
          return;
        }

        const pdim = node.parent.dimension;

        if (node.obj[pdim] < node.parent.obj[pdim]) {
          node.parent.left = null;
        } else {
          node.parent.right = null;
        }
        return;
      }

      // If the right subtree is not empty, swap with the minimum element on the
      // node's dimension. If it is empty, we swap the left and right subtrees and
      // do the same.
      let nextNode, nextObj;

      if (node.right !== null) {
        nextNode = findMin(node.right, node.dimension);
        nextObj = nextNode.obj;
        removeNode(nextNode);
        node.obj = nextObj;
      } else {
        nextNode = findMin(node.left, node.dimension);
        nextObj = nextNode.obj;
        removeNode(nextNode);
        node.right = node.left;
        node.left = null;
        node.obj = nextObj;
      }
    }

    nearest(point, maxNodes) {
      if (maxNodes === undefined) {
        maxNodes = 1;
      }

      let best = new kdtree.heap.MinHeap((x, y) => {
        let res = x[1] - y[1];
        return res;
      });

      const nearestSearch = (node) => {
        let distance = precision(this.metric(point, node.obj));

        if (best.isEmpty()) {
          best.insert([node.obj, distance]);
        } else {
          if (distance < best.peek()[1]) {
            best.insert([node.obj, distance]);
          }
        }

        if (node.right === null && node.left === null) {
          return;
        }

        let bestChild = null;
        if (node.right === null) {
          bestChild = node.left;
        } else if (node.left === null) {
          bestChild = node.right;
        } else {
          if (point[node.dimension] < node.obj[node.dimension]) {
              bestChild = node.left;
          } else {
              bestChild = node.right;
          }
        }

        nearestSearch(bestChild);

        let candidate = [null, null];
        for (let i = 0; i < this.dimensions; i += 1) {
          if (i === node.dimension) {
            candidate[i] = point[i];
          } else {
            candidate[i] = node.obj[i];
          }
        }

        distance = Math.abs(this.metric(candidate, node.obj));

        if (best.size < maxNodes || distance < best.peek()[1]) {
          let otherChild;
          if (bestChild === node.left) {
            otherChild = node.right;
          } else {
            otherChild = node.left;
          }
          if (otherChild !== null) {
            nearestSearch(otherChild);
          }
        }
      }

      if(this.root) {
        nearestSearch(this.root);
      }

      const result = [];

      for (let i=0; i < (Math.min(maxNodes, best.size)); i++) {
        result.push(best.removeHead());
      }

      return result;
    }

    balanceFactor() {
      function height(node) {
        if (node === null) {
          return 0;
        }
        return Math.max(height(node.left), height(node.right)) + 1;
      }

      function count(node) {
        if (node === null) {
          return 0;
        }
        return count(node.left) + count(node.right) + 1;
      }

      return height(this.root) / (Math.log(count(this.root)) / Math.log(2));
    }
  }

  function distance2d(a, b){
    return Math.sqrt(Math.pow(a[0] - b[0], 2) +  Math.pow(a[1] - b[1], 2));
  }

  function create2d(points) {
    return new KDTree(points, distance2d, 2);
  };

  // Types
  kdtree.core.KDTree = KDTree;

  // Factory functions
  kdtree.core.create2d = create2d;
});
<commit_msg>Remove dead code with some cosmetic fixes on kdtree/core.js.<commit_after>/**
 * kdtree
 *
 * Is a modified and google closure adapted kdtree implementation
 * of https://github.com/ubilabs/kd-tree-javascript.
 *
 * @author Andrey Antukh <niwi@niwi.nz>, 2016
 * @author Mircea Pricop <pricop@ubilabs.net>, 2012
 * @author Martin Kleppe <kleppe@ubilabs.net>, 2012
 * @author Ubilabs http://ubilabs.net, 2012
 * @license MIT License <https://opensource.org/licenses/MIT>
 */

goog.provide("kdtree.core");
goog.provide("kdtree.core.KDTree");

goog.require("kdtree.heap");
goog.require("goog.asserts");

goog.scope(function() {
  "use strict";

  const assert = goog.asserts.assert;
  const assertNumber = goog.asserts.assertNumber;

  class Node {
    constructor(obj, dimension, parent) {
      this.obj = obj;
      this.left = null;
      this.right = null;
      this.parent = parent;
      this.dimension = dimension;
    }
  }

  function precision(v) {
    return parseFloat(v.toFixed(6));
  }

  function buildTree(points, depth, parent, dimensions) {
    const dim = depth % dimensions;

    if (points.length === 0) {
      return null;
    }

    if (points.length === 1) {
      return new Node(points[0], dim, parent);
    }

    points.sort((a, b) => {
      return a[dim] - b[dim];
    });

    const median = Math.floor(points.length / 2);
    const node = new Node(points[median], dim, parent);
    node.left = buildTree(points.slice(0, median), depth + 1, node, dimensions);
    node.right = buildTree(points.slice(median + 1), depth + 1, node, dimensions);

    return node;
  }

  function findMin(node, dim) {
    let dimension, own, left, right, min;

    if (node === null) {
      return null;
    }

    if (node.dimension === dim) {
      if (node.left !== null) {
        return findMin(node.left, dim);
      }
      return node;
    }

    own = node.obj[dim];
    left = findMin(node.left, dim);
    right = findMin(node.right, dim);
    min = node;

    if (left !== null && left.obj[dim] < own) {
      min = left;
    }
    if (right !== null && right.obj[dim] < min.obj[dim]) {
      min = right;
    }
    return min;
  }

  function innerSearch(point, node, parent) {
    if (node === null) {
      return parent;
    }

    if (point[dim] < node.obj[dim]) {
      return innerSearch(point, node.left, node);
    } else {
      return innerSearch(point, node.right, node);
    }
  }

  function nodeSearch(point, node) {
    if (node === null) {
      return null;
    }

    if (node.obj === point) {
      return node;
    }

    if (point[node.dimension] < node.obj[node.dimension]) {
      return nodeSearch(point, node.left);
    } else {
      return nodeSearch(point, node.right);
    }
  }

  class KDTree {
    constructor(points, metric, dimensions) {
      assert(points.length !== 0);
      assertNumber(dimensions);

      this.root = buildTree(points, 0, null, dimensions);
      this.metric = metric;
      this.dimensions = dimensions;
    }

    insert(point) {
      const insertPosition = innerSearch(point, this.root, null);

      if (insertPosition === null) {
        this.root = new Node(point, 0, null);
        return;
      }

      const newNode = new Node(point,
                               (insertPosition.dimension + 1) % this.dimensions,
                               insertPosition);

      const dimension = insertPosition.dimension;
      if (point[dimension] < insertPosition.obj[dimension]) {
        insertPosition.left = newNode;
      } else {
        insertPosition.right = newNode;
      }
    }

    remove(point) {
      const node = nodeSearch(point, this.root);
      if (node === null) {
        return;
      }

      if (node.left === null && node.right === null) {
        if (node.parent === null) {
          this.root = null;
          return;
        }

        const pdim = node.parent.dimension;

        if (node.obj[pdim] < node.parent.obj[pdim]) {
          node.parent.left = null;
        } else {
          node.parent.right = null;
        }
        return;
      }

      // If the right subtree is not empty, swap with the minimum element on the
      // node's dimension. If it is empty, we swap the left and right subtrees and
      // do the same.
      let nextNode, nextObj;

      if (node.right !== null) {
        nextNode = findMin(node.right, node.dimension);
        nextObj = nextNode.obj;
        removeNode(nextNode);
        node.obj = nextObj;
      } else {
        nextNode = findMin(node.left, node.dimension);
        nextObj = nextNode.obj;
        removeNode(nextNode);
        node.right = node.left;
        node.left = null;
        node.obj = nextObj;
      }
    }

    nearest(point, maxNodes) {
      if (maxNodes === undefined) {
        maxNodes = 1;
      }

      let best = new kdtree.heap.MinHeap((x, y) => {
        let res = x[1] - y[1];
        return res;
      });

      const nearestSearch = (node) => {
        let distance = precision(this.metric(point, node.obj));

        if (best.isEmpty()) {
          best.insert([node.obj, distance]);
        } else {
          if (distance < best.peek()[1]) {
            best.insert([node.obj, distance]);
          }
        }

        if (node.right === null && node.left === null) {
          return;
        }

        let bestChild = null;
        if (node.right === null) {
          bestChild = node.left;
        } else if (node.left === null) {
          bestChild = node.right;
        } else {
          if (point[node.dimension] < node.obj[node.dimension]) {
              bestChild = node.left;
          } else {
              bestChild = node.right;
          }
        }

        nearestSearch(bestChild);

        let candidate = [null, null];
        for (let i = 0; i < this.dimensions; i += 1) {
          if (i === node.dimension) {
            candidate[i] = point[i];
          } else {
            candidate[i] = node.obj[i];
          }
        }

        distance = Math.abs(this.metric(candidate, node.obj));

        if (best.size < maxNodes || distance < best.peek()[1]) {
          let otherChild;
          if (bestChild === node.left) {
            otherChild = node.right;
          } else {
            otherChild = node.left;
          }
          if (otherChild !== null) {
            nearestSearch(otherChild);
          }
        }
      };

      if(this.root) {
        nearestSearch(this.root);
      }

      const result = [];

      for (let i=0; i < (Math.min(maxNodes, best.size)); i++) {
        result.push(best.removeHead());
      }

      return result;
    }
  }

  function distance2d(a, b){
    return Math.sqrt(Math.pow(a[0] - b[0], 2) +  Math.pow(a[1] - b[1], 2));
  }

  function create2d(points) {
    return new KDTree(points, distance2d, 2);
  };

  // Types
  kdtree.core.KDTree = KDTree;

  // Factory functions
  kdtree.core.create2d = create2d;
});
<|endoftext|>


<commit_before>import './lib/style';
import './main.scss';

const canvas = document.getElementById('js-canvas');
const ctx = canvas.getContext('2d');

const π = Math.PI;
const ππ = 2 * Math.PI;

let ud, lr;
let w, h, hw, hh;
let p = 3000;

function onResize(/*event*/) {
    const {
        innerHeight: height,
        innerWidth: width,
    } = window;

    canvas.height = h = height;
    canvas.width = w = width;
    hh = h / 2;
    hw = w / 2;

    ud = sinWave(0 + hh / 2, h - hh / 2, p);
    lr = cosWave(0 + hw / 2, w - hw / 2, p);
}

window.addEventListener('resize', onResize);
onResize();

function sinWave(min, max, period, offset = 0) {
    return function(ts) {
        return ((max - min) / 2) * (1 + Math.sin((ts + offset) * (ππ / period))) + min;
    }
}

function cosWave(min, max, period, offset = 0) {
    return function(ts) {
        return ((max - min) / 2) * (1 + Math.cos((ts + offset) * (ππ / period))) + min;
    }
}

function draw(ctx, ts) {
    ctx.save();

    ctx.lineWidth = 3;
    ctx.fillStyle = 'rgba(255,255,0,0.65)';
    ctx.strokeStyle = 'rgba(255,0,255,0.85)';

    const x = lr(ts);
    const y = ud(ts);

    ctx.translate(x, y);
    ctx.rotate(Math.atan2(y - hh, x - hw) + π / 2);
    ctx.beginPath();
    ctx.arc(0, 0, 20, π, 0);
    ctx.arc(0, 60, 20, 0, π);
    ctx.closePath();

    ctx.fill();
    ctx.stroke();

    ctx.restore();
}

(function tick(ts = Date.now()) {
    window.requestAnimationFrame(tick);
    ctx.clearRect(0, 0, w, h);
    for (let i = 0, l = 11; i < l; ++ i) {
        draw(ctx, ts + i * (p / l));
    }
})();
<commit_msg>refactor: point the parts 'out'<commit_after>import './lib/style';
import './main.scss';

const canvas = document.getElementById('js-canvas');
const ctx = canvas.getContext('2d');

const π = Math.PI;
const ππ = 2 * Math.PI;

let ud, lr;
let w, h, hw, hh;
let p = 3000;

function onResize(/*event*/) {
    const {
        innerHeight: height,
        innerWidth: width,
    } = window;

    canvas.height = h = height;
    canvas.width = w = width;
    hh = h / 2;
    hw = w / 2;

    ud = sinWave(0 + hh / 2, h - hh / 2, p);
    lr = cosWave(0 + hw / 2, w - hw / 2, p);
}

window.addEventListener('resize', onResize);
onResize();

function sinWave(min, max, period, offset = 0) {
    return function(ts) {
        return ((max - min) / 2) * (1 + Math.sin((ts + offset) * (ππ / period))) + min;
    }
}

function cosWave(min, max, period, offset = 0) {
    return function(ts) {
        return ((max - min) / 2) * (1 + Math.cos((ts + offset) * (ππ / period))) + min;
    }
}

function draw(ctx, ts) {
    ctx.save();

    ctx.lineWidth = 3;
    ctx.fillStyle = 'rgba(255,255,0,0.65)';
    ctx.strokeStyle = 'rgba(255,0,255,0.85)';

    const x = lr(ts);
    const y = ud(ts);

    ctx.translate(x, y);
    ctx.rotate(Math.atan2(y - hh, x - hw) - π / 2);
    ctx.beginPath();
    ctx.arc(0, 0, 20, π, 0);
    ctx.arc(0, 60, 20, 0, π);
    ctx.closePath();

    ctx.fill();
    ctx.stroke();

    ctx.restore();
}

(function tick(ts = Date.now()) {
    window.requestAnimationFrame(tick);
    ctx.clearRect(0, 0, w, h);
    for (let i = 0, l = 11; i < l; ++ i) {
        draw(ctx, ts + i * (p / l));
    }
})();
<|endoftext|>


<commit_before>/*
Copyright 2015 IBM Corp.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name hz.api.cinderAPI
   * @description Provides direct access to Cinder APIs.
   */
  function CinderAPI(apiService) {

    // Volumes

    /**
     * @name hz.api.cinderAPI.getVolumes
     * @description
     * Get a list of volumes.
     *
     * The listing result is an object with property "items." Each item is
     * a volume.
     *
     * @param {Object} params
     * Query parameters. Optional.
     *
     * @param {string} param.search_opts
     * Filters to pass through the API.
     * For example, "status": "available" will show all available volumes.
     */
    this.getVolumes = function(params) {
      var config = (params) ? {'params': params} : {};
      return apiService.get('/api/cinder/volumes/' + config)
        .error(function () {
          horizon.alert('error', gettext('Unable to retrieve volumes.'));
        });
    };

    // Volume Snapshots

    /**
     * @name hz.api.cinderAPI.getVolumeSnapshots
     * @description
     * Get a list of volume snapshots.
     *
     * The listing result is an object with property "items." Each item is
     * a volume snapshot.
     *
     * @param {Object} params
     * Query parameters. Optional.
     *
     * @param {string} param.search_opts
     * Filters to pass through the API.
     * For example, "status": "available" will show all available volume
     * snapshots.
     */
    this.getVolumeSnapshots = function(params) {
      var config = (params) ? {'params': params} : {};
      return apiService.get('/api/cinder/volsnaps/' + config)
        .error(function () {
          horizon.alert('error',
                        gettext('Unable to retrieve volume snapshots.'));
        });
    };
  }

  // Register it with the API module so that anybody using the
  // API module will have access to the Cinder APIs.
  angular.module('hz.api')
    .service('cinderAPI', ['apiService', CinderAPI]);
}());
<commit_msg>REST Angular for Cinder Fix<commit_after>/*
Copyright 2015 IBM Corp.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function () {
  'use strict';

  /**
   * @ngdoc service
   * @name hz.api.cinderAPI
   * @description Provides direct access to Cinder APIs.
   */
  function CinderAPI(apiService) {

    // Volumes

    /**
     * @name hz.api.cinderAPI.getVolumes
     * @description
     * Get a list of volumes.
     *
     * The listing result is an object with property "items." Each item is
     * a volume.
     *
     * @param {Object} params
     * Query parameters. Optional.
     *
     * @param {string} param.search_opts
     * Filters to pass through the API.
     * For example, "status": "available" will show all available volumes.
     */
    this.getVolumes = function(params) {
      var config = (params) ? {'params': params} : {};
      return apiService.get('/api/cinder/volumes/', config)
        .error(function () {
          horizon.alert('error', gettext('Unable to retrieve volumes.'));
        });
    };

    // Volume Snapshots

    /**
     * @name hz.api.cinderAPI.getVolumeSnapshots
     * @description
     * Get a list of volume snapshots.
     *
     * The listing result is an object with property "items." Each item is
     * a volume snapshot.
     *
     * @param {Object} params
     * Query parameters. Optional.
     *
     * @param {string} param.search_opts
     * Filters to pass through the API.
     * For example, "status": "available" will show all available volume
     * snapshots.
     */
    this.getVolumeSnapshots = function(params) {
      var config = (params) ? {'params': params} : {};
      return apiService.get('/api/cinder/volumesnapshots/', config)
        .error(function () {
          horizon.alert('error',
                        gettext('Unable to retrieve volume snapshots.'));
        });
    };
  }

  // Register it with the API module so that anybody using the
  // API module will have access to the Cinder APIs.
  angular.module('hz.api')
    .service('cinderAPI', ['apiService', CinderAPI]);
}());
<|endoftext|>