<commit_before>import { get } from "lodash-es";
import { wsInsertAnalysis, wsUpdateAnalysis, wsRemoveAnalysis } from "../analyses/actions";
import { wsInsertFile, wsUpdateFile, wsRemoveFile } from "../files/actions";
import { wsInsertGroup, wsUpdateGroup, wsRemoveGroup } from "../groups/actions";
import { wsInsertIndex, wsUpdateIndex, wsInsertHistory } from "../indexes/actions";
import { wsInsertJob, wsUpdateJob, wsRemoveJob } from "../jobs/actions";
import { wsInsertOTU, wsUpdateOTU, wsRemoveOTU } from "../otus/actions";
import { wsInsertProcess, wsUpdateProcess } from "../processes/actions";
import { wsInsertReference, wsUpdateReference, wsRemoveReference } from "../references/actions";
import { wsInsertSample, wsUpdateSample, wsRemoveSample } from "../samples/actions";
import { wsUpdateStatus } from "../status/actions";
import { wsInsertSubtraction, wsUpdateSubtraction, wsRemoveSubtraction } from "../subtraction/actions";
import { wsInsertUser, wsUpdateUser, wsRemoveUser } from "../users/actions";

const actionCreatorWrapper = actionCreator => {
    return (state, message) => actionCreator(message.data);
};

const inserters = {
    analyses: (state, message) => {
        const sampleId = get(state, "samples.detail.id");

        if (sampleId && sampleId === message.data.sample.id) {
            return wsInsertAnalysis(message.data);
        }
    },
    files: actionCreatorWrapper(wsInsertFile),
    groups: actionCreatorWrapper(wsInsertGroup),
    history: actionCreatorWrapper(wsInsertHistory),
    indexes: actionCreatorWrapper(wsInsertIndex),
    jobs: actionCreatorWrapper(wsInsertJob),
    otus: actionCreatorWrapper(wsInsertOTU),
    processes: actionCreatorWrapper(wsInsertProcess),
    references: actionCreatorWrapper(wsInsertReference),
    samples: actionCreatorWrapper(wsInsertSample),
    subtraction: actionCreatorWrapper(wsInsertSubtraction),
    users: actionCreatorWrapper(wsInsertUser)
};

const updaters = {
    analyses: (state, message) => {
        const sampleId = get(state, "samples.detail.id");

        if (sampleId && sampleId === message.data.sample.id) {
            return wsUpdateAnalysis(message.data);
        }
    },
    files: actionCreatorWrapper(wsUpdateFile),
    groups: actionCreatorWrapper(wsUpdateGroup),
    indexes: actionCreatorWrapper(wsUpdateIndex),
    jobs: actionCreatorWrapper(wsUpdateJob),
    otus: actionCreatorWrapper(wsUpdateOTU),
    processes: actionCreatorWrapper(wsUpdateProcess),
    references: actionCreatorWrapper(wsUpdateReference),
    samples: actionCreatorWrapper(wsUpdateSample),
    status: actionCreatorWrapper(wsUpdateStatus),
    subtraction: actionCreatorWrapper(wsUpdateSubtraction),
    users: actionCreatorWrapper(wsUpdateUser)
};

const removers = {
    analyses: actionCreatorWrapper(wsRemoveAnalysis),
    files: actionCreatorWrapper(wsRemoveFile),
    groups: actionCreatorWrapper(wsRemoveGroup),
    jobs: actionCreatorWrapper(wsRemoveJob),
    otus: actionCreatorWrapper(wsRemoveOTU),
    references: actionCreatorWrapper(wsRemoveReference),
    samples: actionCreatorWrapper(wsRemoveSample),
    subtraction: actionCreatorWrapper(wsRemoveSubtraction),
    users: actionCreatorWrapper(wsRemoveUser)
};

const modifiers = {
    insert: inserters,
    update: updaters,
    delete: removers
};

export default function WSConnection({ getState, dispatch }) {
    // The Redux store's dispatch method.
    this.dispatch = dispatch;

    this.getState = getState;

    // When a websocket message is received, this method is called with the message as the sole argument. Every message
    // has a property "operation" that tells the dispatcher what to do. Illegal operation names will throw an error.
    this.handle = message => {
        // Reserved word 'interface'; don't use spread syntax.
        const iface = message.interface;
        const operation = message.operation;

        window.console.log(`${iface}.${operation}`);

        const modifier = get(modifiers, [operation, iface]);

        if (modifier) {
            const action = modifier(getState(), message);

            if (action) {
                return dispatch(action);
            }
        }
    };

    this.interval = 500;

    this.establishConnection = () => {
        const protocol = window.location.protocol === "https:" ? "wss" : "ws";

        this.connection = new window.WebSocket(`${protocol}://localhost:9950/ws`);

        this.connection.onopen = () => {
            this.interval = 500;
        };

        this.connection.onmessage = e => {
            this.handle(JSON.parse(e.data));
        };

        this.connection.onclose = () => {
            if (this.interval > 15000) {
                this.interval += 500;
            }

            setTimeout(() => {
                this.establishConnection();
            }, this.interval);
        };
    };
}
<commit_msg>Fix broken Websocket connection in browser<commit_after>import { get } from "lodash-es";
import { wsInsertAnalysis, wsUpdateAnalysis, wsRemoveAnalysis } from "../analyses/actions";
import { wsInsertFile, wsUpdateFile, wsRemoveFile } from "../files/actions";
import { wsInsertGroup, wsUpdateGroup, wsRemoveGroup } from "../groups/actions";
import { wsInsertIndex, wsUpdateIndex, wsInsertHistory } from "../indexes/actions";
import { wsInsertJob, wsUpdateJob, wsRemoveJob } from "../jobs/actions";
import { wsInsertOTU, wsUpdateOTU, wsRemoveOTU } from "../otus/actions";
import { wsInsertProcess, wsUpdateProcess } from "../processes/actions";
import { wsInsertReference, wsUpdateReference, wsRemoveReference } from "../references/actions";
import { wsInsertSample, wsUpdateSample, wsRemoveSample } from "../samples/actions";
import { wsUpdateStatus } from "../status/actions";
import { wsInsertSubtraction, wsUpdateSubtraction, wsRemoveSubtraction } from "../subtraction/actions";
import { wsInsertUser, wsUpdateUser, wsRemoveUser } from "../users/actions";

const actionCreatorWrapper = actionCreator => {
    return (state, message) => actionCreator(message.data);
};

const inserters = {
    analyses: (state, message) => {
        const sampleId = get(state, "samples.detail.id");

        if (sampleId && sampleId === message.data.sample.id) {
            return wsInsertAnalysis(message.data);
        }
    },
    files: actionCreatorWrapper(wsInsertFile),
    groups: actionCreatorWrapper(wsInsertGroup),
    history: actionCreatorWrapper(wsInsertHistory),
    indexes: actionCreatorWrapper(wsInsertIndex),
    jobs: actionCreatorWrapper(wsInsertJob),
    otus: actionCreatorWrapper(wsInsertOTU),
    processes: actionCreatorWrapper(wsInsertProcess),
    references: actionCreatorWrapper(wsInsertReference),
    samples: actionCreatorWrapper(wsInsertSample),
    subtraction: actionCreatorWrapper(wsInsertSubtraction),
    users: actionCreatorWrapper(wsInsertUser)
};

const updaters = {
    analyses: (state, message) => {
        const sampleId = get(state, "samples.detail.id");

        if (sampleId && sampleId === message.data.sample.id) {
            return wsUpdateAnalysis(message.data);
        }
    },
    files: actionCreatorWrapper(wsUpdateFile),
    groups: actionCreatorWrapper(wsUpdateGroup),
    indexes: actionCreatorWrapper(wsUpdateIndex),
    jobs: actionCreatorWrapper(wsUpdateJob),
    otus: actionCreatorWrapper(wsUpdateOTU),
    processes: actionCreatorWrapper(wsUpdateProcess),
    references: actionCreatorWrapper(wsUpdateReference),
    samples: actionCreatorWrapper(wsUpdateSample),
    status: actionCreatorWrapper(wsUpdateStatus),
    subtraction: actionCreatorWrapper(wsUpdateSubtraction),
    users: actionCreatorWrapper(wsUpdateUser)
};

const removers = {
    analyses: actionCreatorWrapper(wsRemoveAnalysis),
    files: actionCreatorWrapper(wsRemoveFile),
    groups: actionCreatorWrapper(wsRemoveGroup),
    jobs: actionCreatorWrapper(wsRemoveJob),
    otus: actionCreatorWrapper(wsRemoveOTU),
    references: actionCreatorWrapper(wsRemoveReference),
    samples: actionCreatorWrapper(wsRemoveSample),
    subtraction: actionCreatorWrapper(wsRemoveSubtraction),
    users: actionCreatorWrapper(wsRemoveUser)
};

const modifiers = {
    insert: inserters,
    update: updaters,
    delete: removers
};

export default function WSConnection({ getState, dispatch }) {
    // The Redux store's dispatch method.
    this.dispatch = dispatch;

    this.getState = getState;

    // When a websocket message is received, this method is called with the message as the sole argument. Every message
    // has a property "operation" that tells the dispatcher what to do. Illegal operation names will throw an error.
    this.handle = message => {
        // Reserved word 'interface'; don't use spread syntax.
        const iface = message.interface;
        const operation = message.operation;

        window.console.log(`${iface}.${operation}`);

        const modifier = get(modifiers, [operation, iface]);

        if (modifier) {
            const action = modifier(getState(), message);

            if (action) {
                return dispatch(action);
            }
        }
    };

    this.interval = 500;

    this.establishConnection = () => {
        const protocol = window.location.protocol === "https:" ? "wss" : "ws";

        this.connection = new window.WebSocket(`${protocol}://${window.location.host}/ws`);

        this.connection.onopen = () => {
            this.interval = 500;
        };

        this.connection.onmessage = e => {
            this.handle(JSON.parse(e.data));
        };

        this.connection.onclose = () => {
            if (this.interval > 15000) {
                this.interval += 500;
            }

            setTimeout(() => {
                this.establishConnection();
            }, this.interval);
        };
    };
}
<|endoftext|>


<commit_before>// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// 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.

/**
 * @fileoverview Constants for HTTP status codes.
 */

goog.provide('goog.net.HttpStatus');

/**
 * HTTP Status Codes defined in RFC 2616.
 * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
 * @enum {number}
 */
goog.net.HttpStatus = {
  // Informational 1xx
  CONTINUE: 100,
  SWITCHING_PROTOCOLS: 101,

  // Successful 2xx
  OK: 200,
  CREATED: 201,
  ACCEPTED: 202,
  NON_AUTHORITATIVE_INFORMATION: 203,
  NO_CONTENT: 204,
  RESET_CONTENT: 205,
  PARTIAL_CONTENT: 206,

  // Redirection 3xx
  MULTIPLE_CHOICES: 300,
  MOVED_PERMANENTLY: 301,
  FOUND: 302,
  SEE_OTHER: 303,
  NOT_MODIFIED: 304,
  USE_PROXY: 305,
  TEMPORARY_REDIRECT: 307,

  // Client Error 4xx
  BAD_REQUEST: 400,
  UNAUTHORIZED: 401,
  PAYMENT_REQUIRED: 402,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  METHOD_NOT_ALLOWED: 405,
  NOT_ACCEPTABLE: 406,
  PROXY_AUTHENTICATION_REQUIRED: 407,
  REQUEST_TIMEOUT: 408,
  CONFLICT: 409,
  GONE: 410,
  LENGTH_REQUIRED: 411,
  PRECONDITION_FAILED: 412,
  REQUEST_ENTITY_TOO_LARGE: 413,
  REQUEST_URI_TOO_LONG: 414,
  UNSUPPORTED_MEDIA_TYPE: 415,
  REQUEST_RANGE_NOT_SATISFIABLE: 416,
  EXPECTATION_FAILED: 417,

  // Server Error 5xx
  INTERNAL_SERVER_ERROR: 500,
  NOT_IMPLEMENTED: 501,
  BAD_GATEWAY: 502,
  SERVICE_UNAVAILABLE: 503,
  GATEWAY_TIMEOUT: 504,
  HTTP_VERSION_NOT_SUPPORTED: 505,

  /*
   * IE returns this code for 204 due to its use of URLMon, which returns this
   * code for 'Operation Aborted'. The status text is 'Unknown', the response
   * headers are ''. Known to occur on IE 6 on XP through IE9 on Win7.
   */
  QUIRK_IE_NO_CONTENT: 1223
};

/**
 * Returns whether the given status should be considered successful.
 *
 * Successful codes are OK (200), CREATED (201), ACCEPTED (202),
 * NO CONTENT (204), NOT MODIFIED (304), and IE's no content code (1223).
 *
 * @param {number} status The status code to test.
 * @return {boolean} Whether the status code should be considered successful.
 */
goog.net.HttpStatus.isSuccess = function(status) {
  switch (status) {
    case goog.net.HttpStatus.OK:
    case goog.net.HttpStatus.CREATED:
    case goog.net.HttpStatus.ACCEPTED:
    case goog.net.HttpStatus.NO_CONTENT:
    case goog.net.HttpStatus.NOT_MODIFIED:
    case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT:
      return true;

    default:
      return false;
  }
};
<commit_msg><commit_after>// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// 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.

/**
 * @fileoverview Constants for HTTP status codes.
 */

goog.provide('goog.net.HttpStatus');

/**
 * HTTP Status Codes defined in RFC 2616.
 * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
 * @enum {number}
 */
goog.net.HttpStatus = {
  // Informational 1xx
  CONTINUE: 100,
  SWITCHING_PROTOCOLS: 101,

  // Successful 2xx
  OK: 200,
  CREATED: 201,
  ACCEPTED: 202,
  NON_AUTHORITATIVE_INFORMATION: 203,
  NO_CONTENT: 204,
  RESET_CONTENT: 205,
  PARTIAL_CONTENT: 206,

  // Redirection 3xx
  MULTIPLE_CHOICES: 300,
  MOVED_PERMANENTLY: 301,
  FOUND: 302,
  SEE_OTHER: 303,
  NOT_MODIFIED: 304,
  USE_PROXY: 305,
  TEMPORARY_REDIRECT: 307,

  // Client Error 4xx
  BAD_REQUEST: 400,
  UNAUTHORIZED: 401,
  PAYMENT_REQUIRED: 402,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  METHOD_NOT_ALLOWED: 405,
  NOT_ACCEPTABLE: 406,
  PROXY_AUTHENTICATION_REQUIRED: 407,
  REQUEST_TIMEOUT: 408,
  CONFLICT: 409,
  GONE: 410,
  LENGTH_REQUIRED: 411,
  PRECONDITION_FAILED: 412,
  REQUEST_ENTITY_TOO_LARGE: 413,
  REQUEST_URI_TOO_LONG: 414,
  UNSUPPORTED_MEDIA_TYPE: 415,
  REQUEST_RANGE_NOT_SATISFIABLE: 416,
  EXPECTATION_FAILED: 417,

  // Server Error 5xx
  INTERNAL_SERVER_ERROR: 500,
  NOT_IMPLEMENTED: 501,
  BAD_GATEWAY: 502,
  SERVICE_UNAVAILABLE: 503,
  GATEWAY_TIMEOUT: 504,
  HTTP_VERSION_NOT_SUPPORTED: 505,

  /*
   * IE returns this code for 204 due to its use of URLMon, which returns this
   * code for 'Operation Aborted'. The status text is 'Unknown', the response
   * headers are ''. Known to occur on IE 6 on XP through IE9 on Win7.
   */
  QUIRK_IE_NO_CONTENT: 1223
};

/**
 * Returns whether the given status should be considered successful.
 *
 * Successful codes are OK (200), CREATED (201), ACCEPTED (202),
 * NO CONTENT (204), PARTIAL CONTENT (206), NOT MODIFIED (304),
 * and IE's no content code (1223).
 *
 * @param {number} status The status code to test.
 * @return {boolean} Whether the status code should be considered successful.
 */
goog.net.HttpStatus.isSuccess = function(status) {
  switch (status) {
    case goog.net.HttpStatus.OK:
    case goog.net.HttpStatus.CREATED:
    case goog.net.HttpStatus.ACCEPTED:
    case goog.net.HttpStatus.NO_CONTENT:
    case goog.net.HttpStatus.PARTIAL_CONTENT:
    case goog.net.HttpStatus.NOT_MODIFIED:
    case goog.net.HttpStatus.QUIRK_IE_NO_CONTENT:
      return true;

    default:
      return false;
  }
};
<|endoftext|>


<commit_before>/**
* Force a value within the boundaries by clamping it to the range `min`, `max`.
*
* @method Phaser.Math#clamp
* @param {float} v - The value to be clamped.
* @param {float} min - The minimum bounds.
* @param {float} max - The maximum bounds.
* @return {number} The clamped value.
*/
var Clamp = function (v, min, max)
{
    if (v < min)
    {
        return min;
    }
    else if (max < v)
    {
        return max;
    }
    else
    {
        return v;
    }
};

module.exports = Clamp;
<commit_msg>Refined Math.Clamp.<commit_after>/**
* Force a value within the boundaries by clamping it to the range `min`, `max`.
*
* @method Phaser.Math#clamp
* @param {float} v - The value to be clamped.
* @param {float} min - The minimum bounds.
* @param {float} max - The maximum bounds.
* @return {number} The clamped value.
*/
var Clamp = function (v, min, max)
{
    return Math.max(min, Math.min(max, value));
};

module.exports = Clamp;
<|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.');
}

if (window.DeviceOrientationEvent) {

    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.2967949,
            lng: -99.1061447,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2995844,
            lng: -99.1070249,
            info:{
                title: 'Bodega Aurrera Hueso',
                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 = 10000;

        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
            }

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

            var scene = document.querySelector('a-scene');

            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"    , "#123123");
            box.setAttribute("look-at"	, "[camera]");

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

            scene.appendChild(box);
        }

    }
};

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>orientation<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.');
}

if (window.DeviceOrientationEvent) {

    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.2967949,
            lng: -99.1061447,
            info:{
                title: 'Walmart Pabellón Cuemanco',
                horario: 'horario',
                promo: 'promo',
                info: 'info',
                desc: 'desc',
                dist: 'dist',
                type: 'supercenter'
            }
        },
        {
            lat: 19.2995844,
            lng: -99.1070249,
            info:{
                title: 'Bodega Aurrera Hueso',
                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 = 10000;

        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 scene = document.querySelector('a-scene');

            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"    , "#123123");
            box.setAttribute("look-at"	, "[camera]");

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

            scene.appendChild(box);
        }

    }
};

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>// SAXON API: http://www.saxonica.com/ce/user-doc/1.1/html/api/

// onSaxonLoad is called when Saxon has finished loading
var onSaxonLoad = function() {
    var xslt = {
        errors:   'jats4r-level-errors.xsl',
        warnings: 'jats4r-level-warnings.xsl',
        info:     'jats4r-level-info.xsl'
    };

    var statusNode = document.getElementById('status');
    statusNode.textContent = 'Choose a JATS XML file to validate.';

    var input = document.getElementById('input');
    var phaseNode = document.getElementById('phase');
    var revalidate = document.getElementById('revalidate');
    var results = document.getElementById('results');

    function validateFile() {
        // clear any previous results
        results.textContent = '';
        if (input.files.length == 0) {
            statusNode.textContent = "Please select a file first!";
            return;
        }
        statusNode.textContent = 'Processing…';

        var reader = new FileReader;
        var phase = phaseNode.value;

        reader.onload = function() {
        	// Parse the input file
        	var doc = Saxon.parseXML(this.result);
        	var pe = doc.querySelector("parsererror");
        	if (pe) {
        		results.insertBefore(pe, null);
        		var h = document.createElement("h2");
        		h.textContent = "Error parsing input file";
        		results.insertBefore(h, pe);
                statusNode.textContent = 'Finished';
        		return;
        	}

            // run the Schematron tests
            // FIXME:  need to parameterize the version number
            Saxon.run({
                stylesheet: '../generated-xsl/0.1/' + xslt[phase],
                source: doc,
                method: 'transformToDocument',
                success: function(processor) {
                    statusNode.textContent = 'Converting…';

                    // Convert the output XML to HTML. When done, this calls updateHTMLDocument,
                    // which uses the @href attribute in the <xsl:result-document> element in the
                    // stylesheet to update the #result element in the HTML page.

                    Saxon.run({
                        stylesheet: 'svrl-to-html.xsl',
                        source: processor.getResultDocument(),
                        method: 'updateHTMLDocument'
                    });

                    statusNode.textContent = 'Finished';
                }
            });
        }

        reader.readAsText(input.files[0]);
    }

    // listen for file selection, or for a press on the "revalidate" button
    input.addEventListener('change', validateFile);
    revalidate.addEventListener('click', validateFile);
}
<commit_msg>Try to get parsing error working in IE<commit_after>// SAXON API: http://www.saxonica.com/ce/user-doc/1.1/html/api/

// onSaxonLoad is called when Saxon has finished loading
var onSaxonLoad = function() {
    var xslt = {
        errors:   'jats4r-level-errors.xsl',
        warnings: 'jats4r-level-warnings.xsl',
        info:     'jats4r-level-info.xsl'
    };

    var statusNode = document.getElementById('status');
    statusNode.textContent = 'Choose a JATS XML file to validate.';

    var input = document.getElementById('input');
    var phaseNode = document.getElementById('phase');
    var revalidate = document.getElementById('revalidate');
    var results = document.getElementById('results');

    function validateFile() {
        // clear any previous results
        results.textContent = '';
        if (input.files.length == 0) {
            statusNode.textContent = "Please select a file first!";
            return;
        }
        statusNode.textContent = 'Processing…';

        var reader = new FileReader;
        var phase = phaseNode.value;

        reader.onload = function() {
        	// Parse the input file
            var parse_error = false;
            try {
                var doc = Saxon.parseXML(this.result);
            }
            catch (e) {
                parse_error = true;
            }
            if (!doc) { parse_error = true; }
            if (!parse_error) {
                var pe = doc.querySelector("parsererror");
            }
        	if (parse_error || pe) {
                if (!pe) {
                    pe = document.createElement("div");
                    pe.textContent = "Unable to parse the input XML file.";
                }
        		results.insertBefore(pe, null);
        		var h = document.createElement("h2");
        		h.textContent = "Error parsing input file";
        		results.insertBefore(h, pe);
                statusNode.textContent = 'Finished';
        		return;
        	}

            // run the Schematron tests
            // FIXME:  need to parameterize the version number
            Saxon.run({
                stylesheet: '../generated-xsl/0.1/' + xslt[phase],
                source: doc,
                method: 'transformToDocument',
                success: function(processor) {
                    statusNode.textContent = 'Converting…';

                    // Convert the output XML to HTML. When done, this calls updateHTMLDocument,
                    // which uses the @href attribute in the <xsl:result-document> element in the
                    // stylesheet to update the #result element in the HTML page.

                    Saxon.run({
                        stylesheet: 'svrl-to-html.xsl',
                        source: processor.getResultDocument(),
                        method: 'updateHTMLDocument'
                    });

                    statusNode.textContent = 'Finished';
                }
            });
        }

        reader.readAsText(input.files[0]);
    }

    // listen for file selection, or for a press on the "revalidate" button
    input.addEventListener('change', validateFile);
    revalidate.addEventListener('click', validateFile);
}
<|endoftext|>


<commit_before>describe("Reformed Churches Locator", function() {

    afterEach(function() {
        // Returns the page to display the home page as it should
        app.navigate(config.test_home_address, {trigger:true})
    });

    describe("'Find a church' page", function() {
        it("should not display an error", function() {
            app.navigate('find_a_church', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('Find a church')
        });
    });

    describe("'Import a directory' page", function() {
        it("should not display an error", function() {
            app.navigate('import_directory', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('downloading')
        });
        function trigger_url_field(){
            $('#url').val('http://opc.org/locator.html')
            $('#url').focus().keyup()
        }
        function directory_type_is_visible(){
            // The test should wait until the AJAX call completes
            // Check to see if the AJAX call returned here
            return $('#directory_type').is(':visible')
        }
        function click_state_radio_button(){
            $("#one_state_per_page").prop("checked",true)
            $("#one_state_per_page").click()
        }
        function state_page_is_visible(){
            return $('#state_page').is(':visible') || ($('#state_page').css('display') != 'none')
        }
        describe('url field', function(){
            it('should display step 2 when a valid URL is entered', function(){
                // TODO: Because this test writes to the database, decide whether
                //  the tests should run in a test copy of the database.
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML", 40000)
                runs(function(){
                    expect($('#directory_type').is(':visible')).toBe(true)
                    // Remove the docs we just created
                    // TODO: Figure out how to refactor this into a general function that can be used in all tests
//                    dir.destroy()
                    // TODO: Improve this to only remove the docs created by this test, rather
                    //  than all docs.
//                    $('#delete_all_docs').click()
                })
            })
        })

        describe('state section', function(){
            it('should display when radio button is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    expect($('#state_page').is(':visible')).toBe(true)
                    // Remove the docs we just created
//                    dir.destroy()
//                    $('#delete_all_docs').click()
                })
            })
        })
        describe('cong details', function(){
            it('should display when select box is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    $('#state_drop_down_selector select[name=state]').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible')
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    expect($('#cong_details_url_selector').is(':visible')).toBe(true)
                    // Remove the docs we just created
//                    dir.destroy()
//                    $('#delete_all_docs').click()
                })
            })
        })
        // TODO: Write test to click on the element with this XPATH:
        //  //*[@id="churchListTable"]/tbody/tr[2]/td[1]/a
    });
});

// General test-runner code
(function() {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;
    var htmlReporter = new jasmine.HtmlReporter();
    jasmineEnv.addReporter(htmlReporter);
    jasmineEnv.specFilter = function(spec) {
        return htmlReporter.specFilter(spec);
    };
    var currentWindowOnload = window.onload;
    window.onload = function() {
        if (currentWindowOnload) {
            currentWindowOnload();
        }
        execJasmine();
    };
    function execJasmine() {
        jasmineEnv.execute();
        // Move Jasmine's symbolSummary to top of page to make it easy to see if
        //    some tests are not passing
        $('body').prepend('

')
        $('.banner').first().prepend($('.symbolSummary'))
    }
})();<commit_msg>Getting unit test to work.<commit_after>describe("Reformed Churches Locator", function() {

    afterEach(function() {
        // Returns the page to display the home page as it should
        app.navigate(config.test_home_address, {trigger:true})
    });

    describe("'Find a church' page", function() {
        it("should not display an error", function() {
            app.navigate('find_a_church', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('Find a church')
        });
    });

    describe("'Import a directory' page", function() {
        it("should not display an error", function() {
            app.navigate('import_directory', { trigger: true })
            var content = $('#content').html()
            expect(content).toMatch('downloading')
        });
        function trigger_url_field(){
            $('#url').val('http://opc.org/locator.html')
            $('#url').focus().keyup()
        }
        function directory_type_is_visible(){
            // The test should wait until the AJAX call completes
            // Check to see if the AJAX call returned here
            return $('#directory_type').is(':visible')
        }
        function click_state_radio_button(){
            $("#one_state_per_page").prop("checked",true)
            $("#one_state_per_page").click()
        }
        function state_page_is_visible(){
            return $('#state_page').is(':visible') || ($('#state_page').css('display') != 'none')
        }
        describe('url field', function(){
            it('should display step 2 when a valid URL is entered', function(){
                // TODO: Because this test writes to the database, decide whether
                //  the tests should run in a test copy of the database.
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML", 60000)
                runs(function(){
                    expect($('#directory_type').is(':visible')).toBe(true)
                    // Remove the docs we just created
                    // TODO: Figure out how to refactor this into a general function that can be used in all tests
//                    dir.destroy()
                    // TODO: Improve this to only remove the docs created by this test, rather
                    //  than all docs.
//                    $('#delete_all_docs').click()
                })
            })
        })

        describe('state section', function(){
            it('should display when radio button is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    expect($('#state_page').is(':visible')).toBe(true)
                    // Remove the docs we just created
//                    dir.destroy()
//                    $('#delete_all_docs').click()
                })
            })
        })
        describe('cong details', function(){
            it('should display when select box is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    $('#state_drop_down_selector select[name=state]').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible')
                },'cong_details_url_selector to be visible', 20000)
                runs(function(){
                    expect($('#cong_details_url_selector').is(':visible')).toBe(true)
                    // Remove the docs we just created
//                    dir.destroy()
//                    $('#delete_all_docs').click()
                })
            })
        })
        // TODO: Write test to click on the element with this XPATH:
        //  //*[@id="churchListTable"]/tbody/tr[2]/td[1]/a
        describe('get congregation id', function(){
            it('should display when link is clicked', function(){
                runs(trigger_url_field)
                waitsFor(directory_type_is_visible, "AJAX call to get URL HTML")
                runs(click_state_radio_button)
                waitsFor(state_page_is_visible, 'state page to display', 20000)
                runs(function(){
                    $('#state_drop_down_selector select[name=state]').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').is(':visible')
                },'cong_details_url_selector to be visible', 60000)
                runs(function(){
                    expect($('#cong_details_url_selector').is(':visible')).toBe(true)
                    // Remove the docs we just created
//                    dir.destroy()
//                    $('#delete_all_docs').click()
                })
                waitsFor(function(){
                    return $('#cong_details_url_selector').html().indexOf('Step 4.5') != -1
                },'cong_details_url_selector to display step 4.5', 60000)
                runs(function(){
                    expect($('#cong_details_url_selector').html()).toMatch('Step 4.5')
                    // Remove the docs we just created
//                    dir.destroy()
//                    $('#delete_all_docs').click()
                })
            })
        })
    });
});

// General test-runner code
(function() {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;
    var htmlReporter = new jasmine.HtmlReporter();
    jasmineEnv.addReporter(htmlReporter);
    jasmineEnv.specFilter = function(spec) {
        return htmlReporter.specFilter(spec);
    };
    var currentWindowOnload = window.onload;
    window.onload = function() {
        if (currentWindowOnload) {
            currentWindowOnload();
        }
        execJasmine();
    };
    function execJasmine() {
        jasmineEnv.execute();
        // Move Jasmine's symbolSummary to top of page to make it easy to see if
        //    some tests are not passing
        $('body').prepend('

')
        $('.banner').first().prepend($('.symbolSummary'))
    }
})();<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.comics',
  name: 'DAOCreateController',

  imports: [
    'stack'
  ],

  exports: [
    'data'
  ],

  properties: [
    {
      name: 'dao',
      hidden: true,
      factory: function() {
        return this.__context__[this.of.id + 'DAO'];
      }
    },
    {
      class: 'Class',
      name: 'of',
      hidden: true
    },
    {
      name: 'data',
      label: '',
      view: { class: 'foam.u2.DetailView' },
      factory: function() {
        return this.of.create(null, this);
      }
    }
  ],

  actions: [
    {
      name: 'save',
      code: function() {
        var stack = self.stack;

        this.dao.put(this.data).then(function() {
          if ( stack ) stack.back();
        });
      }
    },
    {
      name: 'cancel',
      code: function() {
        this.stack && this.stack.back();
      }
    }
  ]
});
<commit_msg>Use foam.String.daoize in DAOCreateController.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * 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.
 */

foam.CLASS({
  package: 'foam.comics',
  name: 'DAOCreateController',

  imports: [
    'stack'
  ],

  exports: [
    'data'
  ],

  properties: [
    {
      name: 'dao',
      hidden: true,
      factory: function() {
        return this.__context__[foam.String.daoize(this.of.name)];
      }
    },
    {
      class: 'Class',
      name: 'of',
      hidden: true
    },
    {
      name: 'data',
      label: '',
      view: { class: 'foam.u2.DetailView' },
      factory: function() {
        return this.of.create(null, this);
      }
    }
  ],

  actions: [
    {
      name: 'save',
      code: function() {
        var stack = self.stack;

        this.dao.put(this.data).then(function() {
          if ( stack ) stack.back();
        });
      }
    },
    {
      name: 'cancel',
      code: function() {
        this.stack && this.stack.back();
      }
    }
  ]
});
<|endoftext|>


<commit_before>var App = require('../../lib/app');
var view = require('../../lib/view');
var i18n = require('../../lib/i18n');
var publish = require('../../lib/publish');
var page = require('page');

var PUBLISH_TIMEOUT = 20000;

module.exports = view.extend({
    id: 'share',
    template: require('./index.html'),
    data: {
        title: 'Share',
        cancel: true,
        error: false,
        isPublishing: true,
        doneDisabled: true
    },
    methods: {
        login: function (e) {
            e.preventDefault();
            this.model.auth.login();
        },
        onDone: function () {
            var self = this;
            if (!self.$data.app.url) return;
            var sms = 'sms:?body=' +
                encodeURIComponent(self.$data.shareMessage);
            window.location = sms;
            page('/make/' + self.$parent.$data.params.id + '/detail');
        }
    },
    ready: function () {
        var self = this;

        // Fetch app
        var id = self.$parent.$data.params.id;
        var app = new App(id);

        // Bind app
        self.$data.app = app.data;

        // Bind user
        self.$data.user = self.model.data.user;

        // Share message
        var message = i18n
            .get('share_message')
            .replace('{{app.name}}', app.data.name);
        self.$data.shareMessage = message + ': ' + app.data.url;

        if (!global.location.search.match('publish=true') && app.data.url) {
            self.$data.isPublishing = false;
            return;
        }

        // Publish
        console.log('Starting publish...');
        self.$data.doneDisabled = true;

        var sync = self.model._sync;
        var syncTimeout;

        function onSynced() {
            publish(id, self.$data.user.username, function (err, data) {
                global.clearTimeout(syncTimeout);
                self.$data.isPublishing = false;
                if (err) {
                    console.error(err);
                    self.$data.error = (err.status || 'Error') +
                        ': ' + err.message;
                    return;
                }
                console.log('Published!');
                self.$data.error = false;
                self.$data.doneDisabled = false;
                app.data.url = data.url;
                self.$data.shareMessage = message + ': ' + data.url;
            });
        }

        syncTimeout = global.setTimeout(function () {
            console.log('timed out');
            self.$data.isPublishing = false;
            self.$data.error = 'Oops! Your publish is taking too long';
        }, PUBLISH_TIMEOUT);

        if (self.model._dirty) {
            sync.once('completed', onSynced);
        } else {
            onSynced();
        }

    }
});
<commit_msg>publish<commit_after>var App = require('../../lib/app');
var view = require('../../lib/view');
var i18n = require('../../lib/i18n');
var publish = require('../../lib/publish');
var page = require('page');

var PUBLISH_TIMEOUT = 20000;

module.exports = view.extend({
    id: 'share',
    template: require('./index.html'),
    data: {
        title: 'Share',
        cancel: true,
        error: false,
        isPublishing: true,
        doneDisabled: true
    },
    methods: {
        login: function (e) {
            e.preventDefault();
            this.model.auth.login();
        },
        onDone: function () {
            var self = this;
            if (!self.$data.app.url) return;
            var sms = 'sms:?body=' +
                encodeURIComponent(self.$data.shareMessage);
            window.location = sms;
            page('/make/' + self.$parent.$data.params.id + '/detail');
        }
    },
    ready: function () {
        var self = this;

        // Fetch app
        var id = self.$parent.$data.params.id;
        var app = new App(id);

        // Bind app
        self.$data.app = app.data;

        // Bind user
        self.$data.user = self.model.data.user;

        // Share message
        var message = i18n
            .get('share_message')
            .replace('{{app.name}}', app.data.name);
        self.$data.shareMessage = message + ': ' + app.data.url;

        if (!global.location.search.match('publish=true') && app.data.url) {
            self.$data.isPublishing = false;
            return;
        }

        // Publish
        console.log('Starting publish...');
        self.$data.doneDisabled = true;

        var syncTimeout = global.setTimeout(function () {
            console.log('timed out');
            self.$data.isPublishing = false;
            self.$data.error = 'Oops! Your publish is taking too long';
        }, PUBLISH_TIMEOUT);

        publish(id, self.$data.user.username, function (err, data) {
            global.clearTimeout(syncTimeout);
            self.$data.isPublishing = false;
            if (err) {
                console.error(err);
                self.$data.error = (err.status || 'Error') +
                    ': ' + err.message;
                return;
            }
            console.log('Published!');
            self.$data.error = false;
            self.$data.doneDisabled = false;
            app.data.url = data.url;
            self.$data.shareMessage = message + ': ' + data.url;
        });

    }
});
<|endoftext|>


<commit_before>let moment = require('moment-timezone');
require('moment/locale/en-gb');
moment.locale("en-gb");

describe('Arrivals page', () => {
  const schDateString = moment().format("YYYY-MM-DD");

  const schTimeString = "00:55:00";
  const estTimeString = "01:05:00";
  const actTimeString = "01:07:00";
  const estChoxTimeString = "01:11:00";
  const actChoxTimeString = "01:12:00";

  const schString = schDateString + "T" + schTimeString + "Z";
  const estString = schDateString + "T" + estTimeString + "Z";
  const actString = schDateString + "T" + actTimeString + "Z";
  const estChoxString = schDateString + "T" + estChoxTimeString + "Z";
  const actChoxString = schDateString + "T" + actChoxTimeString + "Z";

  const millis = moment(schString).unix() * 1000;

  function addFlight() {
    cy.setRoles(["test"]);
    cy.addFlight(estString, actString, estChoxString, actChoxString, schString);
  }

  function loadManifestFixture() {
    cy.setRoles(["test"]);
    cy.request('POST', '/test/manifest', manifest);
  }

  before(() => {
    cy.setRoles(["test"]);
    cy.deleteData();
  });

  after(() => {
    cy.setRoles(["test"]);
    cy.deleteData();
  });

  const manifest = {
    "EventCode": "DC",
    "DeparturePortCode": "AMS",
    "VoyageNumberTrailingLetter": "",
    "ArrivalPortCode": "STN",
    "DeparturePortCountryCode": "MAR",
    "VoyageNumber": "0123",
    "VoyageKey": "key",
    "ScheduledDateOfDeparture": schDateString,
    "ScheduledDateOfArrival": schDateString,
    "CarrierType": "AIR",
    "CarrierCode": "TS",
    "ScheduledTimeOfDeparture": "06:30:00",
    "ScheduledTimeOfArrival": schTimeString,
    "FileId": "fileID",
    "PassengerList": [
      {
        "DocumentIssuingCountryCode": "GBR",
        "PersonType": "P",
        "DocumentLevel": "Primary",
        "Age": "30",
        "DisembarkationPortCode": "",
        "InTransitFlag": "N",
        "DisembarkationPortCountryCode": "",
        "NationalityCountryEEAFlag": "EEA",
        "PassengerIdentifier": "",
        "DocumentType": "P",
        "PoavKey": "1",
        "NationalityCountryCode": "GBR"
      },
      {
        "DocumentIssuingCountryCode": "ZWE",
        "PersonType": "P",
        "DocumentLevel": "Primary",
        "Age": "30",
        "DisembarkationPortCode": "",
        "InTransitFlag": "N",
        "DisembarkationPortCountryCode": "",
        "NationalityCountryEEAFlag": "",
        "PassengerIdentifier": "",
        "DocumentType": "P",
        "PoavKey": "2",
        "NationalityCountryCode": "ZWE"
      },
      {
        "DocumentIssuingCountryCode": "AUS",
        "PersonType": "P",
        "DocumentLevel": "Primary",
        "Age": "30",
        "DisembarkationPortCode": "",
        "InTransitFlag": "N",
        "DisembarkationPortCountryCode": "",
        "NationalityCountryEEAFlag": "",
        "PassengerIdentifier": "",
        "DocumentType": "P",
        "PoavKey": "3",
        "NationalityCountryCode": "AUS"
      }
    ]
  };

  const schTimeLocal = moment(schString).tz("Europe/London").format("HH:mm")
  const estTimeLocal = moment(estString).tz("Europe/London").format("HH:mm")
  const actTimeLocal = moment(actString).tz("Europe/London").format("HH:mm")
  const estChoxTimeLocal = moment(estChoxString).tz("Europe/London").format("HH:mm")
  const actChoxTimeLocal = moment(actChoxString).tz("Europe/London").format("HH:mm")
  const pcpTimeLocal = moment(actChoxString).add(13, "minutes").tz("Europe/London").format("HH:mm")

  const csvWithNoApiSplits = "IATA,ICAO,Origin,Gate/Stand,Status,Scheduled Date,Scheduled Time,Est Arrival,Act Arrival,Est " +
    "Chox,Act Chox,Est PCP,Total Pax,PCP Pax,API e-Gates,API EEA,API Non-EEA,API Fast Track,Historical e-Gates,Historical " +
    "EEA,Historical Non-EEA,Historical Fast Track,Terminal Average e-Gates,Terminal Average EEA,Terminal " +
    "Average Non-EEA,Terminal Average Fast Track" + "\n" +
    "TS0123,TS0123,AMS,46/44R,On Chocks," + schDateString + "," + schTimeLocal + "," + estTimeLocal + "," + actTimeLocal + "," + estChoxTimeLocal + "," + actChoxTimeLocal + "," + pcpTimeLocal + ",51,51,17,0,34,,,,,,13,37,1,";

  const csvWithAPISplits = "IATA,ICAO,Origin,Gate/Stand,Status,Scheduled Date,Scheduled Time,Est Arrival,Act Arrival," +
    "Est Chox,Act Chox,Est PCP,Total Pax,PCP Pax,API e-Gates,API EEA,API Non-EEA,API Fast Track,Historical e-Gates," +
    "Historical EEA,Historical Non-EEA,Historical Fast Track,Terminal Average e-Gates,Terminal Average EEA,Terminal " +
    "Average Non-EEA,Terminal Average Fast Track,API Actual - EEA (Machine Readable),API Actual - Non EEA (Non Visa)," +
    "API Actual - Non EEA (Visa),API Actual - eGates" + "\n" +
    "TS0123,TS0123,AMS,46/44R,On Chocks," + schDateString + "," + schTimeLocal + "," + estTimeLocal + "," + actTimeLocal + "," + estChoxTimeLocal + "," + actChoxTimeLocal + "," + pcpTimeLocal + ",51,51,17,0,34,,,,,,13,37,1,,0.0,1.0,1.0,1.0";

  it('Displays a flight after it has been ingested via the live feed', () => {
    addFlight();
    cy.visit('#terminal/T1/current/arrivals/?timeRangeStart=0&timeRangeEnd=24');
    cy.get("#arrivals").contains("TS0123")
  });

  it('Does not show API splits in the flights export for regular users', () => {
    loadManifestFixture();
    cy.setRoles(["test"]);
    cy.request('POST', '/test/manifest', manifest);
    cy.visit('#terminal/T1/current/arrivals/?timeRangeStart=0&timeRangeEnd=24');
    cy.get('.pax-api');
    cy.request('GET', '/export/arrivals/' + millis + '/T1?startHour=0&endHour=24').then((resp) => {
      expect(resp.body).to.equal(csvWithNoApiSplits);
    });
  });

  it('Allows you to view API splits in the flights export for users with api:view permission', () => {
    loadManifestFixture();
    cy.setRoles(["test", "api:view"]);
    cy.request({
      method: 'GET',
      url: '/export/arrivals/' + millis + '/T1?startHour=0&endHour=24',
    }).then((resp) => {
      expect(resp.body).to.equal(csvWithAPISplits)
    })
  });
});
<commit_msg>DRT-5473 add timeout for test :(<commit_after>let moment = require('moment-timezone');
require('moment/locale/en-gb');
moment.locale("en-gb");

describe('Arrivals page', () => {
  const schDateString = moment().format("YYYY-MM-DD");

  const schTimeString = "00:55:00";
  const estTimeString = "01:05:00";
  const actTimeString = "01:07:00";
  const estChoxTimeString = "01:11:00";
  const actChoxTimeString = "01:12:00";

  const schString = schDateString + "T" + schTimeString + "Z";
  const estString = schDateString + "T" + estTimeString + "Z";
  const actString = schDateString + "T" + actTimeString + "Z";
  const estChoxString = schDateString + "T" + estChoxTimeString + "Z";
  const actChoxString = schDateString + "T" + actChoxTimeString + "Z";

  const millis = moment(schString).unix() * 1000;

  function addFlight() {
    cy.setRoles(["test"]);
    cy.addFlight(estString, actString, estChoxString, actChoxString, schString);
  }

  function loadManifestFixture() {
    cy.setRoles(["test"]);
    cy.request('POST', '/test/manifest', manifest);
  }

  before(() => {
    cy.setRoles(["test"]);
    cy.deleteData();
  });

  after(() => {
    cy.setRoles(["test"]);
    cy.deleteData();
  });

  const manifest = {
    "EventCode": "DC",
    "DeparturePortCode": "AMS",
    "VoyageNumberTrailingLetter": "",
    "ArrivalPortCode": "STN",
    "DeparturePortCountryCode": "MAR",
    "VoyageNumber": "0123",
    "VoyageKey": "key",
    "ScheduledDateOfDeparture": schDateString,
    "ScheduledDateOfArrival": schDateString,
    "CarrierType": "AIR",
    "CarrierCode": "TS",
    "ScheduledTimeOfDeparture": "06:30:00",
    "ScheduledTimeOfArrival": schTimeString,
    "FileId": "fileID",
    "PassengerList": [
      {
        "DocumentIssuingCountryCode": "GBR",
        "PersonType": "P",
        "DocumentLevel": "Primary",
        "Age": "30",
        "DisembarkationPortCode": "",
        "InTransitFlag": "N",
        "DisembarkationPortCountryCode": "",
        "NationalityCountryEEAFlag": "EEA",
        "PassengerIdentifier": "",
        "DocumentType": "P",
        "PoavKey": "1",
        "NationalityCountryCode": "GBR"
      },
      {
        "DocumentIssuingCountryCode": "ZWE",
        "PersonType": "P",
        "DocumentLevel": "Primary",
        "Age": "30",
        "DisembarkationPortCode": "",
        "InTransitFlag": "N",
        "DisembarkationPortCountryCode": "",
        "NationalityCountryEEAFlag": "",
        "PassengerIdentifier": "",
        "DocumentType": "P",
        "PoavKey": "2",
        "NationalityCountryCode": "ZWE"
      },
      {
        "DocumentIssuingCountryCode": "AUS",
        "PersonType": "P",
        "DocumentLevel": "Primary",
        "Age": "30",
        "DisembarkationPortCode": "",
        "InTransitFlag": "N",
        "DisembarkationPortCountryCode": "",
        "NationalityCountryEEAFlag": "",
        "PassengerIdentifier": "",
        "DocumentType": "P",
        "PoavKey": "3",
        "NationalityCountryCode": "AUS"
      }
    ]
  };

  const schTimeLocal = moment(schString).tz("Europe/London").format("HH:mm")
  const estTimeLocal = moment(estString).tz("Europe/London").format("HH:mm")
  const actTimeLocal = moment(actString).tz("Europe/London").format("HH:mm")
  const estChoxTimeLocal = moment(estChoxString).tz("Europe/London").format("HH:mm")
  const actChoxTimeLocal = moment(actChoxString).tz("Europe/London").format("HH:mm")
  const pcpTimeLocal = moment(actChoxString).add(13, "minutes").tz("Europe/London").format("HH:mm")

  const csvWithNoApiSplits = "IATA,ICAO,Origin,Gate/Stand,Status,Scheduled Date,Scheduled Time,Est Arrival,Act Arrival,Est " +
    "Chox,Act Chox,Est PCP,Total Pax,PCP Pax,API e-Gates,API EEA,API Non-EEA,API Fast Track,Historical e-Gates,Historical " +
    "EEA,Historical Non-EEA,Historical Fast Track,Terminal Average e-Gates,Terminal Average EEA,Terminal " +
    "Average Non-EEA,Terminal Average Fast Track" + "\n" +
    "TS0123,TS0123,AMS,46/44R,On Chocks," + schDateString + "," + schTimeLocal + "," + estTimeLocal + "," + actTimeLocal + "," + estChoxTimeLocal + "," + actChoxTimeLocal + "," + pcpTimeLocal + ",51,51,17,0,34,,,,,,13,37,1,";

  const csvWithAPISplits = "IATA,ICAO,Origin,Gate/Stand,Status,Scheduled Date,Scheduled Time,Est Arrival,Act Arrival," +
    "Est Chox,Act Chox,Est PCP,Total Pax,PCP Pax,API e-Gates,API EEA,API Non-EEA,API Fast Track,Historical e-Gates," +
    "Historical EEA,Historical Non-EEA,Historical Fast Track,Terminal Average e-Gates,Terminal Average EEA,Terminal " +
    "Average Non-EEA,Terminal Average Fast Track,API Actual - EEA (Machine Readable),API Actual - Non EEA (Non Visa)," +
    "API Actual - Non EEA (Visa),API Actual - eGates" + "\n" +
    "TS0123,TS0123,AMS,46/44R,On Chocks," + schDateString + "," + schTimeLocal + "," + estTimeLocal + "," + actTimeLocal + "," + estChoxTimeLocal + "," + actChoxTimeLocal + "," + pcpTimeLocal + ",51,51,17,0,34,,,,,,13,37,1,,0.0,1.0,1.0,1.0";

  it('Displays a flight after it has been ingested via the live feed', () => {
    addFlight();
    cy.visit('#terminal/T1/current/arrivals/?timeRangeStart=0&timeRangeEnd=24');
    cy.get("#arrivals").contains("TS0123")
  });

  it('Does not show API splits in the flights export for regular users', () => {
    cy.setRoles(["test"]);
    cy.request('POST', '/test/manifest', manifest);
    cy.visit('#terminal/T1/current/arrivals/?timeRangeStart=0&timeRangeEnd=24');
    cy.wait(2000);
    cy.reload();
    cy.get('.pax-api');
    cy.request('GET', '/export/arrivals/' + millis + '/T1?startHour=0&endHour=24').then((resp) => {
      expect(resp.body).to.equal(csvWithNoApiSplits);
    });
  });

  it('Allows you to view API splits in the flights export for users with api:view permission', () => {
    loadManifestFixture();
    cy.setRoles(["test", "api:view"]);
    cy.request({
      method: 'GET',
      url: '/export/arrivals/' + millis + '/T1?startHour=0&endHour=24',
    }).then((resp) => {
      expect(resp.body).to.equal(csvWithAPISplits)
    })
  });
});
<|endoftext|>


<commit_before>'use strict';

var React = require('react');
var ReactDOM = require('react-dom');

var containmentPropType = React.PropTypes.any;

if (typeof window !== 'undefined') {
  containmentPropType = React.PropTypes.instanceOf(window.Element);
}

function throttle (callback, limit) {
    var wait = false;
    return function () {
        if (!wait) {
            wait = true;
            setTimeout(function () {
                callback.call();
                wait = false;
            }, limit);
        }
    }
}

function debounce(func, wait) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
      timeout = null;
      func.apply(context, args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

module.exports = React.createClass({
  displayName: 'VisibilitySensor',

  propTypes: {
    onChange: React.PropTypes.func.isRequired,
    active: React.PropTypes.bool,
    partialVisibility: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
    ]),
    delayedCall: React.PropTypes.bool,
    scrollCheck: React.PropTypes.bool,
    scrollDelay: React.PropTypes.number,
    intervalCheck: React.PropTypes.bool,
    intervalDelay: React.PropTypes.number,
    containment: containmentPropType,
    children: React.PropTypes.element,
    minTopValue: React.PropTypes.number
  },

  getDefaultProps: function () {
    return {
      active: true,
      partialVisibility: false,
      minTopValue: 0,
      scrollCheck: false,
      scrollDelay: 250,
      throttleScroll: false,
      throttleLimit: 50,
      intervalCheck: true,
      intervalDelay: 100,
      delayedCall: false,
      containment: null,
      children: React.createElement('span')
    };
  },

  getInitialState: function () {
    return {
      isVisible: null,
      visibilityRect: {}
    };
  },

  componentDidMount: function () {
    this.node = ReactDOM.findDOMNode(this);
    if (this.props.active) {
      this.startWatching();
    }
  },

  componentWillUnmount: function () {
    this.stopWatching();
  },

 componentWillReceiveProps: function (nextProps) {
    if (nextProps.active) {
      this.setState(this.getInitialState());
      this.startWatching();
    } else {
      this.stopWatching();
    }
  },

  getContainer: function () {
    return this.props.containment || window;
  },

  startWatching: function () {
    if (this.debounceCheck || this.interval) { return; }

    if (this.props.intervalCheck) {
      this.interval = setInterval(this.check, this.props.intervalDelay);
    }

    if (this.props.throttleScroll) {
      this.debounceCheck = throttle(this.check, this.props.throttleLimit);
      this.getContainer().addEventListener('scroll', this.debounceCheck);
    } else if (this.props.scrollCheck) {
      this.debounceCheck = debounce(this.check, this.props.scrollDelay);
      this.getContainer().addEventListener('scroll', this.debounceCheck);
    }

    // if dont need delayed call, check on load ( before the first interval fires )
    !this.props.delayedCall && this.check();
  },

  stopWatching: function () {
    if (this.debounceCheck) {
      this.getContainer().removeEventListener('scroll', this.debounceCheck);
      this.debounceCheck = null;
    }
    if (this.interval) { this.interval = clearInterval(this.interval); }
  },

  /**
   * Check if the element is within the visible viewport
   */
  check: function () {
    console.log(this.props)
    var el = this.node;
    var rect;
    var containmentRect;
    // if the component has rendered to null, dont update visibility
    if (!el) {
      return this.state;
    }

    rect = el.getBoundingClientRect();

    if (this.props.containment) {
      containmentRect = this.props.containment.getBoundingClientRect();
    } else {
      containmentRect = {
        top: 0,
        left: 0,
        bottom: window.innerHeight || document.documentElement.clientHeight,
        right: window.innerWidth || document.documentElement.clientWidth
      };
    }

    var visibilityRect = {
      top: rect.top >= containmentRect.top,
      left: rect.left >= containmentRect.left,
      bottom: rect.bottom <= containmentRect.bottom,
      right: rect.right <= containmentRect.right
    };

    var isVisible = (
      visibilityRect.top &&
      visibilityRect.left &&
      visibilityRect.bottom &&
      visibilityRect.right
    );

    // check for partial visibility
    if (this.props.partialVisibility) {
      var partialVisible =
          rect.top <= containmentRect.bottom && rect.bottom >= containmentRect.top &&
          rect.left <= containmentRect.right && rect.right >= containmentRect.left;

      // account for partial visibility on a single edge
      if (typeof this.props.partialVisibility === 'string') {
        partialVisible = visibilityRect[this.props.partialVisibility]
      }

      // if we have minimum top visibility set by props, lets check, if it meets the passed value
      // so if for instance element is at least 200px in viewport, then show it.
      isVisible = this.props.minTopValue
        ? partialVisible && rect.top <= (containmentRect.bottom - this.props.minTopValue)
        : partialVisible
    }

    var state = this.state;
    // notify the parent when the value changes
    if (this.state.isVisible !== isVisible) {
      state = {
        isVisible: isVisible,
        visibilityRect: visibilityRect
      };
      this.setState(state);
      this.props.onChange(isVisible, visibilityRect);
    }

    return state;
  },

  render: function () {
    return React.Children.only(this.props.children);
  }
});
<commit_msg>Adding prop types<commit_after>'use strict';

var React = require('react');
var ReactDOM = require('react-dom');

var containmentPropType = React.PropTypes.any;

if (typeof window !== 'undefined') {
  containmentPropType = React.PropTypes.instanceOf(window.Element);
}

function throttle (callback, limit) {
    var wait = false;
    return function () {
        if (!wait) {
            wait = true;
            setTimeout(function () {
                callback.call();
                wait = false;
            }, limit);
        }
    }
}

function debounce(func, wait) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
      timeout = null;
      func.apply(context, args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

module.exports = React.createClass({
  displayName: 'VisibilitySensor',

  propTypes: {
    onChange: React.PropTypes.func.isRequired,
    active: React.PropTypes.bool,
    partialVisibility: React.PropTypes.oneOfType([
      React.PropTypes.bool,
      React.PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
    ]),
    delayedCall: React.PropTypes.bool,
    scrollCheck: React.PropTypes.bool,
    scrollDelay: React.PropTypes.number,
    throttleScroll: React.PropTypes.bool,
    throttleLimit: React.PropTypes.number,
    intervalCheck: React.PropTypes.bool,
    intervalDelay: React.PropTypes.number,
    containment: containmentPropType,
    children: React.PropTypes.element,
    minTopValue: React.PropTypes.number,
  },

  getDefaultProps: function () {
    return {
      active: true,
      partialVisibility: false,
      minTopValue: 0,
      scrollCheck: false,
      scrollDelay: 250,
      throttleScroll: false,
      throttleLimit: 50,
      intervalCheck: true,
      intervalDelay: 100,
      delayedCall: false,
      containment: null,
      children: React.createElement('span')
    };
  },

  getInitialState: function () {
    return {
      isVisible: null,
      visibilityRect: {}
    };
  },

  componentDidMount: function () {
    this.node = ReactDOM.findDOMNode(this);
    if (this.props.active) {
      this.startWatching();
    }
  },

  componentWillUnmount: function () {
    this.stopWatching();
  },

 componentWillReceiveProps: function (nextProps) {
    if (nextProps.active) {
      this.setState(this.getInitialState());
      this.startWatching();
    } else {
      this.stopWatching();
    }
  },

  getContainer: function () {
    return this.props.containment || window;
  },

  startWatching: function () {
    if (this.debounceCheck || this.interval) { return; }

    if (this.props.intervalCheck) {
      this.interval = setInterval(this.check, this.props.intervalDelay);
    }

    if (this.props.throttleScroll) {
      this.debounceCheck = throttle(this.check, this.props.throttleLimit);
      this.getContainer().addEventListener('scroll', this.debounceCheck);
    } else if (this.props.scrollCheck) {
      this.debounceCheck = debounce(this.check, this.props.scrollDelay);
      this.getContainer().addEventListener('scroll', this.debounceCheck);
    }

    // if dont need delayed call, check on load ( before the first interval fires )
    !this.props.delayedCall && this.check();
  },

  stopWatching: function () {
    if (this.debounceCheck) {
      this.getContainer().removeEventListener('scroll', this.debounceCheck);
      this.debounceCheck = null;
    }
    if (this.interval) { this.interval = clearInterval(this.interval); }
  },

  /**
   * Check if the element is within the visible viewport
   */
  check: function () {
    var el = this.node;
    var rect;
    var containmentRect;
    // if the component has rendered to null, dont update visibility
    if (!el) {
      return this.state;
    }

    rect = el.getBoundingClientRect();

    if (this.props.containment) {
      containmentRect = this.props.containment.getBoundingClientRect();
    } else {
      containmentRect = {
        top: 0,
        left: 0,
        bottom: window.innerHeight || document.documentElement.clientHeight,
        right: window.innerWidth || document.documentElement.clientWidth
      };
    }

    var visibilityRect = {
      top: rect.top >= containmentRect.top,
      left: rect.left >= containmentRect.left,
      bottom: rect.bottom <= containmentRect.bottom,
      right: rect.right <= containmentRect.right
    };

    var isVisible = (
      visibilityRect.top &&
      visibilityRect.left &&
      visibilityRect.bottom &&
      visibilityRect.right
    );

    // check for partial visibility
    if (this.props.partialVisibility) {
      var partialVisible =
          rect.top <= containmentRect.bottom && rect.bottom >= containmentRect.top &&
          rect.left <= containmentRect.right && rect.right >= containmentRect.left;

      // account for partial visibility on a single edge
      if (typeof this.props.partialVisibility === 'string') {
        partialVisible = visibilityRect[this.props.partialVisibility]
      }

      // if we have minimum top visibility set by props, lets check, if it meets the passed value
      // so if for instance element is at least 200px in viewport, then show it.
      isVisible = this.props.minTopValue
        ? partialVisible && rect.top <= (containmentRect.bottom - this.props.minTopValue)
        : partialVisible
    }

    var state = this.state;
    // notify the parent when the value changes
    if (this.state.isVisible !== isVisible) {
      state = {
        isVisible: isVisible,
        visibilityRect: visibilityRect
      };
      this.setState(state);
      this.props.onChange(isVisible, visibilityRect);
    }

    return state;
  },

  render: function () {
    return React.Children.only(this.props.children);
  }
});
<|endoftext|>


<commit_before>define([
	'goo/entities/systems/System',
	'goo/renderer/Renderer',
	'goo/math/Matrix4x4',
	'goo/math/MathUtils',
	'goo/math/Vector3'
],
/** @lends */
function (
	System,
	Renderer,
	Matrix4x4,
	MathUtils,
	Vector3
	) {
	'use strict';

	/**
	 * @class
	 * @extends System
	 */
	function HtmlSystem(renderer) {
		System.call(this, 'HtmlSystem', ['TransformComponent', 'HtmlComponent']);
		this.renderer = renderer;
	}

	HtmlSystem.prototype = Object.create(System.prototype);

	//
	// Browsers implement z-index as signed 32bit int.
	// Overflowing pushes the element to the back.
	//
	var MAX_Z_INDEX = 2147483647;

	var tmpVector = new Vector3();

	// Copied from CSSTransformComponent
	var prefixes = ["", "-webkit-", "-moz-", "-ms-", "-o-"];
	var setStyle = function (element, property, style) {
		for (var j = 0; j < prefixes.length; j++) {
			element.style[prefixes[j] + property] = style;
		}
	};

	HtmlSystem.prototype.process = function (entities) {
		if (entities.length === 0) {
			return;
		}

		var camera = Renderer.mainCamera;
		var screenWidth = this.renderer.domElement.width;
		var screenHeight = this.renderer.domElement.height;

		for (var i = 0; i < entities.length; i++) {
			var entity = entities[i];
			var component = entity.htmlComponent;

			// Always show if not using transform (except if not hidden)
			if (!component.useTransformComponent) {
				component.domElement.style.display = component.hidden ? 'none' : '';
				setStyle(component.domElement, 'transform', '');
				continue;
			}

			// Hidden
			if (component.hidden) {
				component.domElement.style.display = 'none';
				continue;
			}

			// Behind camera
			tmpVector.setv(camera.translation)
				.subv(entity.transformComponent.worldTransform.translation);
			if (camera._direction.dot(tmpVector) > 0) {
				component.domElement.style.display = 'none';
				continue;
			}

			// compute world position.
			camera.getScreenCoordinates(entity.transformComponent.worldTransform.translation, screenWidth, screenHeight, tmpVector);
			// Behind near plane
			if (tmpVector.z < 0) {
				if (component.hidden !== true) {
					component.domElement.style.display = 'none';
					//component.hidden = true;
				}
				continue;
			}
			// Else visible
			component.domElement.style.display = '';

			var renderer = this.renderer;
			var devicePixelRatio = renderer._useDevicePixelRatio && window.devicePixelRatio ? window.devicePixelRatio / renderer.svg.currentScale : 1;
			var fx = Math.floor(tmpVector.x / devicePixelRatio);
			var fy = Math.floor(tmpVector.y / devicePixelRatio);

			setStyle(component.domElement, 'transform',
				'translate(-50%, -50%) ' +
				'translate(' + fx + 'px, ' + fy + 'px)' +
				'translate(' + renderer.domElement.offsetLeft + 'px, ' + renderer.domElement.offsetTop + 'px)');

			component.domElement.style.zIndex = MAX_Z_INDEX - Math.round(tmpVector.z * MAX_Z_INDEX);
		}
	};

	return HtmlSystem;
});
<commit_msg>Review on hidden html component #1524<commit_after>define([
	'goo/entities/systems/System',
	'goo/renderer/Renderer',
	'goo/math/Matrix4x4',
	'goo/math/MathUtils',
	'goo/math/Vector3'
],
/** @lends */
function (
	System,
	Renderer,
	Matrix4x4,
	MathUtils,
	Vector3
	) {
	'use strict';

	/**
	 * @class
	 * @extends System
	 */
	function HtmlSystem(renderer) {
		System.call(this, 'HtmlSystem', ['TransformComponent', 'HtmlComponent']);
		this.renderer = renderer;
	}

	HtmlSystem.prototype = Object.create(System.prototype);

	//
	// Browsers implement z-index as signed 32bit int.
	// Overflowing pushes the element to the back.
	//
	var MAX_Z_INDEX = 2147483647;

	var tmpVector = new Vector3();

	// Copied from CSSTransformComponent
	var prefixes = ["", "-webkit-", "-moz-", "-ms-", "-o-"];
	var setStyle = function (element, property, style) {
		for (var j = 0; j < prefixes.length; j++) {
			element.style[prefixes[j] + property] = style;
		}
	};

	HtmlSystem.prototype.process = function (entities) {
		if (entities.length === 0) {
			return;
		}

		var camera = Renderer.mainCamera;
		var screenWidth = this.renderer.domElement.width;
		var screenHeight = this.renderer.domElement.height;

		for (var i = 0; i < entities.length; i++) {
			var entity = entities[i];
			var component = entity.htmlComponent;

			// Always show if not using transform (if not hidden)
			if (!component.useTransformComponent) {
				component.domElement.style.display = component.hidden ? 'none' : '';
				setStyle(component.domElement, 'transform', '');
				continue;
			}

			// Hidden
			if (component.hidden) {
				component.domElement.style.display = 'none';
				continue;
			}

			// Behind camera
			tmpVector.setv(camera.translation)
				.subv(entity.transformComponent.worldTransform.translation);
			if (camera._direction.dot(tmpVector) > 0) {
				component.domElement.style.display = 'none';
				continue;
			}

			// compute world position.
			camera.getScreenCoordinates(entity.transformComponent.worldTransform.translation, screenWidth, screenHeight, tmpVector);
			// Behind near plane
			if (tmpVector.z < 0) {
				if (component.hidden !== true) {
					component.domElement.style.display = 'none';
					//component.hidden = true;
				}
				continue;
			}
			// Else visible
			component.domElement.style.display = '';

			var renderer = this.renderer;
			var devicePixelRatio = renderer._useDevicePixelRatio && window.devicePixelRatio ? window.devicePixelRatio / renderer.svg.currentScale : 1;
			var fx = Math.floor(tmpVector.x / devicePixelRatio);
			var fy = Math.floor(tmpVector.y / devicePixelRatio);

			setStyle(component.domElement, 'transform',
				'translate(-50%, -50%) ' +
				'translate(' + fx + 'px, ' + fy + 'px)' +
				'translate(' + renderer.domElement.offsetLeft + 'px, ' + renderer.domElement.offsetTop + 'px)');

			component.domElement.style.zIndex = MAX_Z_INDEX - Math.round(tmpVector.z * MAX_Z_INDEX);
		}
	};

	return HtmlSystem;
});
<|endoftext|>


<commit_before>/**
 * @private
 * @name pc.gfx.VertexElementType
 * @description DEPRECATED. Constants for primitive type.
 */
pc.gfx.VertexElementType = {
    INT8: 0,
    UINT8: 1,
    INT16: 2,
    UINT16: 3,
    INT32: 4,
    UINT32: 5,
    FLOAT32: 6
};

pc.extend(pc.gfx, function () {
    var _typeSize = [];
    _typeSize[pc.gfx.ELEMENTTYPE_INT8   ] = 1;
    _typeSize[pc.gfx.ELEMENTTYPE_UINT8  ] = 1;
    _typeSize[pc.gfx.ELEMENTTYPE_INT16  ] = 2;
    _typeSize[pc.gfx.ELEMENTTYPE_UINT16 ] = 2;
    _typeSize[pc.gfx.ELEMENTTYPE_INT32  ] = 4;
    _typeSize[pc.gfx.ELEMENTTYPE_UINT32 ] = 4;
    _typeSize[pc.gfx.ELEMENTTYPE_FLOAT32] = 4;

    /**
     * @name pc.gfx.VertexElement
     * @class An attribute stored in a vertex buffer. Positions, normals, texture coordinates
     * and vertex colors are all examples of vertex elements.
     * @param {String} semantic The semantic of the vertex element (see pc.gfx.SEMANTIC_*).
     * @param {Number} numComponents The number of distinct components in this particular element.
     * @param {pc.gfx.VertexElementType} dataType The type of each element component.
     * @param {Boolean} normalize If true, map integer values to the range 0 to 1, otherwise leave
     * them unaltered. Defaults to false.
     */
    var VertexElement = function (semantic, numComponents, dataType, normalize) {
        this.name = semantic;

        // These will be initialized by the VertexFormat constructor
        this.offset = 0;
        this.stride = 0;

        // This is used by the graphics device to tag the associated stream
        this.stream = -1;

        // Initialize scope id to something sensible
        this.scopeId = null; // Initialized when setting vertex buffer in the graphics device

        // Store the data type information
        this.dataType      = dataType;
        this.numComponents = numComponents;

        this.normalize = (typeof normalize === 'undefined') ? false : normalize;

        // Calculate the size
        this.size = this.numComponents * _typeSize[this.dataType];
    };

    return {
        VertexElement: VertexElement
    };
}());<commit_msg>Remove vertex element JS file.<commit_after><|endoftext|>