<commit_before>
(function () {
    'use strict';

    /* ngInject */
    function Navigation (
        $q, $interval, $rootScope, $timeout,
        $geolocation,
        Config
    ) {

        var events = {
            positionUpdated: 'nih.navigation.positionUpdated',
            positionOffCourse: 'nih.navigation.positionOffCourse'
        };
        var position = {
            point: null,
            properties: null,
            destination: null
        };
        var stepLengthFeet = Config.stepLengthFeet || 100;
        var stepLengthMiles = stepLengthFeet / 5280;
        var currentRoute = {
            stepBoxes: [],
            geom: null, // linestring
            distance: 0,
            stepped: 0
        };
        var originalDestination = null;

        var module = {
            getCurrentPosition: getCurrentPosition,
            isRerouting: isRerouting,
            offCourse: offCourse,
            getDestination: getDestination,
            setDestination: setDestination,
            setRoute: setRoute,
            stepCurrent: stepCurrent,
            stepNext: stepNext,
            stepPrevious: stepPrevious,
            stepFirst: stepFirst,
            stepLast: stepLast
        };

        return module;

        /**
         * getCurrentPosition wrapper for geolocation operations
         * This function signature should match $geolocation.getCurrentPosition
         *
         * Currently stubbed with mock location configured in config.js, returns private position
         * object if set, otherwise the Config.stubs.geolocation
         *
         * @return {promise} Resolve with Geolocation object or reject with messages
         */
        function getCurrentPosition() {
            // Could replace this with a call to $geolocation and pass through the promises
            var point = position.point;
            var latitude = Config.stubs.geolocation.latitude;
            var longitude = Config.stubs.geolocation.longitude;
            if (point) {
                latitude = point.geometry.coordinates[1];
                longitude = point.geometry.coordinates[0];
            }
            var geolocation = {
                coords: {
                    latitude: latitude,
                    longitude: longitude
                }
            };
            var dfd = $q.defer();
            $timeout(function () {
                dfd.resolve(geolocation);
            }, 100);
            return dfd.promise;
        }

        /**
         * Trigger an 'off-route' location value, by using the current route + location and routing
         *     choosing a point 90 degrees off the route by a few hundred feet
         *
         * Does nothing if a route does not exist
         *
         * Triggers events.positionOffCourse event
         */
        function offCourse() {
            getCurrentPosition().then(function (position) {
                if (!routeExists()) {
                    return;
                }
                var startPoint = turf.point([position.coords.longitude, position.coords.latitude]);
                var nextRoutePoint = turf.along(currentRoute.geom, currentRoute.stepped + stepLengthMiles, 'miles');
                var currentBearing = turf.bearing(startPoint, nextRoutePoint);
                var bearing = currentBearing + 90;
                if (bearing > 180) {
                    bearing -= 360;
                }
                var reroutePoint = turf.destination(startPoint, stepLengthMiles * 2, bearing, 'miles');
                $rootScope.$broadcast(events.positionOffCourse, reroutePoint);
            });
        }

        function getDestination() {
            return originalDestination;
        }

        function setDestination(destination) {
            originalDestination = destination;
        }

        /**
         * Set navigation route to a geojson object returned by Directions.get
         * @param {FeatureCollection} newRoute Feature collection of linestrings with directions properties
         */
        function setRoute(geojsonRoute) {
            var coordinates = _(geojsonRoute.features)
                .map(function (feature) { return feature.geometry.coordinates; })
                .flatten(true)
                .value();

            // Flatten the original FeatureCollection linestring to a single linestring
            //  so we can properly step along it
            // Only reset the line string if the route is new
            var newLinestring = turf.linestring(coordinates);
            if (!linestringEquals(currentRoute.geom, newLinestring)) {
                currentRoute.stepBoxes = generateStepBoxes(geojsonRoute);
                currentRoute.geom = turf.linestring(coordinates);
                currentRoute.distance = turf.lineDistance(currentRoute.geom, 'miles');
                currentRoute.stepped = 0;
            }
        }

        function stepNext() {
            currentRoute.stepped += stepLengthMiles;
            setPosition(currentRoute.stepped);
        }

        function stepPrevious() {
            currentRoute.stepped -= stepLengthMiles;
            setPosition(currentRoute.stepped);
        }

        function stepFirst() {
            setPosition(0);
        }

        function stepLast() {
            setPosition(currentRoute.distance);
        }

        function stepCurrent() {
            setPosition(currentRoute.stepped);
        }

        function setPosition(distance) {
            if (distance > currentRoute.distance) {
                distance = currentRoute.distance;
                currentRoute.stepped = currentRoute.distance;
            }
            if (distance < 0) {
                distance = 0;
                currentRoute.stepped = 0;
            }
            if (routeExists()) {
                var point = turf.along(currentRoute.geom, distance, 'miles');
                var stepBox = findStepBoxForPoint(point, currentRoute.stepped);
                if (stepBox) {
                    // Pass all relevant position info
                    //  point, properties, next destination point
                    position.point = point;
                    position.properties = stepBox.properties;
                    position.destination = stepBox.destinationPoint;
                    $rootScope.$broadcast(events.positionUpdated, position);
                }
            }
        }

        function routeExists() {
            return !!(currentRoute.geom);
        }

        function isRerouting() {
            if (!(currentRoute.geom && currentRoute.geom.geometry)) {
                return false;
            }
            var src = turf.point(originalDestination);
            var dest = turf.point(_(currentRoute.geom.geometry.coordinates).last());
            var distanceMeters = turf.distance(src, dest, 'kilometers') * 1000;
            return distanceMeters > 25;
        }

        /**
         * Foreach step in the route geojson, return a stepBox object
         *
         *  StepBox: {
         *      polygon: a slightly buffered polygon feature that surrounds the points on the route step
         *      destinationPoint: the last Point on the route step
         *      properties: the properties object of the next step in the route (has directions info)
         *      distance: {
         *          min: Number the min distance that this step box is along the route
         *          max: Number the max distance that this step box is along the route
         *      }
         *  }
         *
         * @param  {[type]} geojson [description]
         * @return {object}         Array of stepBox objects, see above
         */
        function generateStepBoxes(geojson) {
            var lastDirection = {
                directions: {
                    text: 'Arrive at destination'
                }
            };
            var stepBoxes = [];
            var numFeatures = geojson.features.length;
            var totalDistance = 0;
            angular.forEach(geojson.features, function (feature, index) {
                var length = feature.geometry.coordinates.length;
                var lastPoint = turf.point(feature.geometry.coordinates[length - 1]);
                // Get the next feature's properties, because the next directions for the current
                //  step are on the next feature
                var nextFeature = index < numFeatures - 1 ? geojson.features[index + 1] : null;
                // If we're at the last feature, return the last directions text instead
                var properties = nextFeature ? nextFeature.properties : lastDirection;
                var lineLength = turf.lineDistance(feature, 'miles');
                var minDistance = totalDistance;
                var maxDistance = minDistance + lineLength;
                var stepBox = {
                    polygon: turf.buffer(turf.envelope(feature), stepLengthMiles * 0.25, 'miles').features[0],
                    destinationPoint: lastPoint,
                    properties: properties,
                    distance: {
                        min: minDistance,
                        max: maxDistance
                    }
                };
                stepBoxes.push(stepBox);
                totalDistance += lineLength;
            });
            return stepBoxes;
        }

        // For our purposes in determining whether the linestring route geom has changed, two
        // linestrings are equal if their lengths match and the first and last points in the
        // line are the same
        function linestringEquals(a, b) {
            if (!a || !b || a.length !== b.length) {
                return false;
            }
            var len = a.geometry.coordinates.length;
            var aFirst = a.geometry.coordinates[0];
            var bFirst = b.geometry.coordinates[0];
            var aLast = a.geometry.coordinates[len - 1];
            var bLast = b.geometry.coordinates[len - 1];
            if (aFirst[0] === bFirst[0] && aFirst[1] === bFirst[1] &&
                aLast[0] === bLast[0] && aLast[1] === bLast[1]) {
                return true;
            } else {
                return false;
            }
        }

        /**
         * Returns the stepBox that contains the passed Point feature
         * @param  {object Point} point point to search the stepboxes for a match
         * @param  {Number} distance distance along route that the passed point is
         * @return {object}       the stepbox or undefined
         */
        function findStepBoxForPoint(point, distance) {
            return _.find(currentRoute.stepBoxes, function (stepBox) {
                return turf.inside(point, stepBox.polygon) && distance >= stepBox.distance.min && distance <= stepBox.distance.max;
            });
        }
    }

    angular.module('nih.navigation')
      .factory('Navigation', Navigation);

})();
<commit_msg>Bugfix linestring eq array out of bounds<commit_after>
(function () {
    'use strict';

    /* ngInject */
    function Navigation (
        $q, $interval, $rootScope, $timeout,
        $geolocation,
        Config
    ) {

        var events = {
            positionUpdated: 'nih.navigation.positionUpdated',
            positionOffCourse: 'nih.navigation.positionOffCourse'
        };
        var position = {
            point: null,
            properties: null,
            destination: null
        };
        var stepLengthFeet = Config.stepLengthFeet || 100;
        var stepLengthMiles = stepLengthFeet / 5280;
        var currentRoute = {
            stepBoxes: [],
            geom: null, // linestring
            distance: 0,
            stepped: 0
        };
        var originalDestination = null;

        var module = {
            getCurrentPosition: getCurrentPosition,
            isRerouting: isRerouting,
            offCourse: offCourse,
            getDestination: getDestination,
            setDestination: setDestination,
            setRoute: setRoute,
            stepCurrent: stepCurrent,
            stepNext: stepNext,
            stepPrevious: stepPrevious,
            stepFirst: stepFirst,
            stepLast: stepLast
        };

        return module;

        /**
         * getCurrentPosition wrapper for geolocation operations
         * This function signature should match $geolocation.getCurrentPosition
         *
         * Currently stubbed with mock location configured in config.js, returns private position
         * object if set, otherwise the Config.stubs.geolocation
         *
         * @return {promise} Resolve with Geolocation object or reject with messages
         */
        function getCurrentPosition() {
            // Could replace this with a call to $geolocation and pass through the promises
            var point = position.point;
            var latitude = Config.stubs.geolocation.latitude;
            var longitude = Config.stubs.geolocation.longitude;
            if (point) {
                latitude = point.geometry.coordinates[1];
                longitude = point.geometry.coordinates[0];
            }
            var geolocation = {
                coords: {
                    latitude: latitude,
                    longitude: longitude
                }
            };
            var dfd = $q.defer();
            $timeout(function () {
                dfd.resolve(geolocation);
            }, 100);
            return dfd.promise;
        }

        /**
         * Trigger an 'off-route' location value, by using the current route + location and routing
         *     choosing a point 90 degrees off the route by a few hundred feet
         *
         * Does nothing if a route does not exist
         *
         * Triggers events.positionOffCourse event
         */
        function offCourse() {
            getCurrentPosition().then(function (position) {
                if (!routeExists()) {
                    return;
                }
                var startPoint = turf.point([position.coords.longitude, position.coords.latitude]);
                var nextRoutePoint = turf.along(currentRoute.geom, currentRoute.stepped + stepLengthMiles, 'miles');
                var currentBearing = turf.bearing(startPoint, nextRoutePoint);
                var bearing = currentBearing + 90;
                if (bearing > 180) {
                    bearing -= 360;
                }
                var reroutePoint = turf.destination(startPoint, stepLengthMiles * 2, bearing, 'miles');
                $rootScope.$broadcast(events.positionOffCourse, reroutePoint);
            });
        }

        function getDestination() {
            return originalDestination;
        }

        function setDestination(destination) {
            originalDestination = destination;
        }

        /**
         * Set navigation route to a geojson object returned by Directions.get
         * @param {FeatureCollection} newRoute Feature collection of linestrings with directions properties
         */
        function setRoute(geojsonRoute) {
            var coordinates = _(geojsonRoute.features)
                .map(function (feature) { return feature.geometry.coordinates; })
                .flatten(true)
                .value();

            // Flatten the original FeatureCollection linestring to a single linestring
            //  so we can properly step along it
            // Only reset the line string if the route is new
            var newLinestring = turf.linestring(coordinates);
            if (!linestringEquals(currentRoute.geom, newLinestring)) {
                currentRoute.stepBoxes = generateStepBoxes(geojsonRoute);
                currentRoute.geom = turf.linestring(coordinates);
                currentRoute.distance = turf.lineDistance(currentRoute.geom, 'miles');
                currentRoute.stepped = 0;
            }
        }

        function stepNext() {
            currentRoute.stepped += stepLengthMiles;
            setPosition(currentRoute.stepped);
        }

        function stepPrevious() {
            currentRoute.stepped -= stepLengthMiles;
            setPosition(currentRoute.stepped);
        }

        function stepFirst() {
            setPosition(0);
        }

        function stepLast() {
            setPosition(currentRoute.distance);
        }

        function stepCurrent() {
            setPosition(currentRoute.stepped);
        }

        function setPosition(distance) {
            if (distance > currentRoute.distance) {
                distance = currentRoute.distance;
                currentRoute.stepped = currentRoute.distance;
            }
            if (distance < 0) {
                distance = 0;
                currentRoute.stepped = 0;
            }
            if (routeExists()) {
                var point = turf.along(currentRoute.geom, distance, 'miles');
                var stepBox = findStepBoxForPoint(point, currentRoute.stepped);
                if (stepBox) {
                    // Pass all relevant position info
                    //  point, properties, next destination point
                    position.point = point;
                    position.properties = stepBox.properties;
                    position.destination = stepBox.destinationPoint;
                    $rootScope.$broadcast(events.positionUpdated, position);
                }
            }
        }

        function routeExists() {
            return !!(currentRoute.geom);
        }

        function isRerouting() {
            if (!(currentRoute.geom && currentRoute.geom.geometry)) {
                return false;
            }
            var src = turf.point(originalDestination);
            var dest = turf.point(_(currentRoute.geom.geometry.coordinates).last());
            var distanceMeters = turf.distance(src, dest, 'kilometers') * 1000;
            return distanceMeters > 25;
        }

        /**
         * Foreach step in the route geojson, return a stepBox object
         *
         *  StepBox: {
         *      polygon: a slightly buffered polygon feature that surrounds the points on the route step
         *      destinationPoint: the last Point on the route step
         *      properties: the properties object of the next step in the route (has directions info)
         *      distance: {
         *          min: Number the min distance that this step box is along the route
         *          max: Number the max distance that this step box is along the route
         *      }
         *  }
         *
         * @param  {[type]} geojson [description]
         * @return {object}         Array of stepBox objects, see above
         */
        function generateStepBoxes(geojson) {
            var lastDirection = {
                directions: {
                    text: 'Arrive at destination'
                }
            };
            var stepBoxes = [];
            var numFeatures = geojson.features.length;
            var totalDistance = 0;
            angular.forEach(geojson.features, function (feature, index) {
                var length = feature.geometry.coordinates.length;
                var lastPoint = turf.point(feature.geometry.coordinates[length - 1]);
                // Get the next feature's properties, because the next directions for the current
                //  step are on the next feature
                var nextFeature = index < numFeatures - 1 ? geojson.features[index + 1] : null;
                // If we're at the last feature, return the last directions text instead
                var properties = nextFeature ? nextFeature.properties : lastDirection;
                var lineLength = turf.lineDistance(feature, 'miles');
                var minDistance = totalDistance;
                var maxDistance = minDistance + lineLength;
                var stepBox = {
                    polygon: turf.buffer(turf.envelope(feature), stepLengthMiles * 0.25, 'miles').features[0],
                    destinationPoint: lastPoint,
                    properties: properties,
                    distance: {
                        min: minDistance,
                        max: maxDistance
                    }
                };
                stepBoxes.push(stepBox);
                totalDistance += lineLength;
            });
            return stepBoxes;
        }

        // For our purposes in determining whether the linestring route geom has changed, two
        // linestrings are equal if their lengths match and the first and last points in the
        // line are the same
        function linestringEquals(a, b) {
            if (!a || !b || a.length !== b.length) {
                return false;
            }
            var aLen = a.geometry.coordinates.length;
            var bLen = b.geometry.coordinates.length;
            var aFirst = a.geometry.coordinates[0];
            var bFirst = b.geometry.coordinates[0];
            var aLast = a.geometry.coordinates[aLen - 1];
            var bLast = b.geometry.coordinates[bLen - 1];
            if (aFirst[0] === bFirst[0] && aFirst[1] === bFirst[1] &&
                aLast[0] === bLast[0] && aLast[1] === bLast[1]) {
                return true;
            } else {
                return false;
            }
        }

        /**
         * Returns the stepBox that contains the passed Point feature
         * @param  {object Point} point point to search the stepboxes for a match
         * @param  {Number} distance distance along route that the passed point is
         * @return {object}       the stepbox or undefined
         */
        function findStepBoxForPoint(point, distance) {
            return _.find(currentRoute.stepBoxes, function (stepBox) {
                return turf.inside(point, stepBox.polygon) && distance >= stepBox.distance.min && distance <= stepBox.distance.max;
            });
        }
    }

    angular.module('nih.navigation')
      .factory('Navigation', Navigation);

})();
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
 */

/**
 * This file contains utility functions for Openstack components
 */

var authApi = require('../../../common/auth.api');
var configUtils = require('../../../common/config.utils');
var httpsOp = require('../../../common/httpsoptions.api');
var logutils = require('../../../utils/log.utils');
var commonUtils = require('../../../utils/common.utils');

/* Function: getIpProtoByServCatPubUrl
    This function is used to parse the publicURL/internalURL got from keystone catalog,
    And returns protocol (http/https), IP and port of the service
    publicURL/internalURL can be any of below formats:
    http://xxx.xxx.xxx.xxx:xxxx/v2.0 and
    xxx.xxx.xxx.xxx:xxxx/v2.0 and
 */
function getIpProtoByServCatPubUrl (pubUrl)
{
    var ipAddr = null;
    var port = null;
    var reqProto = global.PROTOCOL_HTTP;
    var ipAddrStr = pubUrl, portStr = null;
    var ipIdx = -1, portIdx = -1;

    ipIdx = pubUrl.indexOf(global.HTTPS_URL);
    if (ipIdx >= 0) {
        reqProto = global.PROTOCOL_HTTPS;
        ipAddrStr = pubUrl.slice(ipIdx + (global.HTTPS_URL).length);
    }
    ipIdx = pubUrl.indexOf(global.HTTP_URL);
    if (ipIdx >= 0) {
        ipAddrStr = pubUrl.slice(ipIdx + (global.HTTP_URL).length);
    }

    /* Format is http://<ip/host>:<port>/XXXX */
    portIdx = ipAddrStr.indexOf(':');
    if (-1 != portIdx) {
        ipAddr = ipAddrStr.substr(0, portIdx);
        portStr = ipAddrStr.slice(portIdx + 1);
        portIdx = portStr.indexOf('/');
        if (-1 != portIdx) {
            port = portStr.substr(0, portIdx);
        } else {
            port = portStr;
        }
    }
    return {'ipAddr': ipAddr, 'port': port, 'protocol': reqProto};
}

function getServiceApiVersionObjByPubUrl (pubUrl, type)
{
    if (null == pubUrl) {
        return null;
    }
    var ipProtoObj = getIpProtoByServCatPubUrl(pubUrl);
    var reqProto = ipProtoObj['protocol'];
    var ipAddr = ipProtoObj['ipAddr'];
    var port = ipProtoObj['port'];
    var version = null;

    switch (type) {
    case 'compute':
    case 'volume':
        try {
            var idx = pubUrl.lastIndexOf('/');
            if (-1 == idx) {
                return null;
            }
            var str = pubUrl.substr(0, idx);
            idx = str.lastIndexOf('/');
            if (-1 == idx) {
                return null;
            }
            version = str.slice(idx + 1);
        } catch(e) {
            logutils.logger.error('volume|compute pubUrl parse error' + e);
        }
        break;
    case 'image':
    case 'identity':
        try {
            var defVer = getDfltEndPointValueByType(type, 'version');
            var protoIdx = pubUrl.indexOf('://');
            if (protoIdx >= 0) {
                pubUrl = pubUrl.slice(protoIdx + '://'.length);
            }
            var idx = pubUrl.indexOf('/');
            if (idx >= 0) {
                pubUrl = pubUrl.slice(idx + 1);
                idx = pubUrl.indexOf('/');
                if (idx >= 0) {
                    /* Format: http://localhost:9292/v1/ or
                     * localhost:9292/v1/
                     */
                    version = pubUrl.substr(0, idx);
                } else {
                    if (!pubUrl.length) {
                        /* Format: http://localhost:9292/ or
                         * localhost:9292/
                         */
                        version = defVer;
                    } else {
                        /* Format: http://localhost:9292/v1 or
                         * localhost:9292/v1
                         */
                        version = pubUrl;
                    }
                }
            } else {
                /* Format: http://localhost:9292 or localhost:9292 */
                version = defVer;
            }
        } catch(e) {
            logutils.logger.error(type +' pubUrl parse error' + e);
        }
        break;
    default:
        break;
    }
    return {version: version, ip: ipAddr, protocol: reqProto, port: port};
}

/* Function: getApiTypeByServiceType
   Maps service type to webServer Server type
 */
function getApiTypeByServiceType (servType)
{
    switch (servType) {
    case global.SERVICE_ENDPT_TYPE_COMPUTE:
        return global.label.COMPUTE_SERVER;
    case global.SERVICE_ENDPT_TYPE_IMAGE:
        return global.label.IMAGE_SERVER;
    case global.SERVICE_ENDPT_TYPE_NETWORK:
        return global.label.NETWORK_SERVER;
    case global.SERVICE_ENDPT_TYPE_IDENTITY:
        return global.label.IDENTITY_SERVER;
    case global.SERVICE_ENDPT_TYPE_VOLUME:
        return global.label.STORAGE_SERVER;
    default:
        return servType;
    }
}

/* Function: getOStackModuleApiVersion
   Get the API Version from Config File, if not specified then take default
   suppoted API Versions
 */
function getOStackModuleApiVersion (apiType)
{
    var version = httpsOp.getHttpsOptionsByAPIType(apiType, 'apiVersion');
    if (null == version) {
        switch (apiType) {
        case global.label.IMAGE_SERVER:
            return glanceApi.imageListVerList;
        case global.label.COMPUTE_SERVER:
            return novaApi.novaAPIVerList;
        default:
            return null;
        }
    }
    return version;
}

/* Function: getDfltEndPointValueByType
   Get the version etc info by end point module types
 */
function getDfltEndPointValueByType (module, type)
{
    switch (module) {
    case 'image':
        if ('version' == type) {
            return 'v1';
        }
        break;
    case 'nova':
        if ('version' == type) {
            return 'v1.1';
        }
        break;
    case 'identity':
        if ('version' == type) {
            return 'v2.0';
        }
        break;
    default:
        break;
    }
    return null;
}

/* Function: getServiceAPIVersionByReqObj
    Get openStack Module API Version, IP, Port, Protocol from
    publicURL/internalURL in keystone catalog response
 */
function getServiceAPIVersionByReqObj (req, appData, type, callback, reqBy)
{
    var redirectToLogout = true;
    var dataObjArr = [];
    var endPtList = [];
    var config = configUtils.getConfig();

    var endPtFromConfig = config.serviceEndPointFromConfig;
    if (null == endPtFromConfig) {
        endPtFromConfig = true;
    }
    if (true == endPtFromConfig) {
        if ((type ==
             authApi.getEndpointServiceType(global.DEFAULT_CONTRAIL_API_IDENTIFIER)) ||
            (type ==
             authApi.getEndpointServiceType(global.DEFAULT_CONTRAIL_ANALYTICS_IDENTIFIER))) {
            /* for opServer and apiServer, we will be getting directly from
             * apiRestApi
             */
            callback(null);
            return;
        }
        var apiType = getApiTypeByServiceType(type);
        ip = httpsOp.getHttpsOptionsByAPIType(apiType, 'ip');
        port = httpsOp.getHttpsOptionsByAPIType(apiType, 'port');
        version = getOStackModuleApiVersion(apiType);
        protocol = httpsOp.getHttpsOptionsByAPIType(apiType, 'authProtocol');
        if ((null == ip) || (null == port) || (null == version) ||
            (null == protocol)) {
            logutils.logger.error("ip/port/apiVersion/authProtocol not found in" +
                                  " config file for:" + apiType);
            callback(null);
            return;
        }
        var verLen = version.length;
        for (var i = 0; i < verLen; i++) {
            dataObjArr.push({'version': version[i], 'protocol': protocol, 'ip': ip,
                            'port': port});
        }
        if (!dataObjArr.length) {
            logutils.logger.error('apiVersion for ' + type + ' is NULL');
            callback(null);
        } else {
            dataObjArr.sort(function(a, b) {
                if (b['version'] > a['version']) {
                    return 1;
                } else if (b['version'] < a['version']) {
                    return -1;
                } else {
                    return 0;
                }
            });
            callback(dataObjArr);
        }
        return;
    }
    var regionCookie =
        commonUtils.getValueByJsonPath(req, 'cookies;region', null, false);
    if (null == regionCookie) {
        callback(null, null, redirectToLogout);
        return;
    }
    var regionName = authApi.getCurrentRegion(req);
    var reqRegion = commonUtils.getValueByJsonPath(appData, "authObj;reqRegion",
                                                   null);
    if (null != reqRegion) {
        regionName = reqRegion;
    }
    if ((null != regionName) && ('undefined' != regionName)) {
        serviceCatalog =
            commonUtils.getValueByJsonPath(req, 'session;serviceCatalog;' +
                                           regionName, null, false);
    } else {
        serviceCatalog = commonUtils.getValueByJsonPath(req,
                                                        'session;serviceCatalog',
                                                        null, false);
        if (null != serviceCatalog) {
            for (var key in serviceCatalog) {
                regionName = key;
                req.session.regionname = regionName;
                serviceCatalog = serviceCatalog[key];
                break;
            }
        }
    }
    if (null != serviceCatalog) {
        mappedObj = null;
        try {
            mappedObjs = serviceCatalog[type].maps;
        } catch(e) {
            mappedObjs = null;
        }
        if ((null != mappedObjs) && (null != mappedObjs[0])) {
            callback(mappedObjs, regionName);
            return;
        }
    }
    authApi.getServiceCatalog(req, function(accessData) {
        if ((null == accessData) || (null == accessData.serviceCatalog)) {
            callback(null, null, redirectToLogout);
            return;
        }
        var keySt = require('./keystone.api');
        var svcCatalog =
            keySt.getServiceCatalogByRegion(req, regionName, accessData);
        var firstRegion = null;
        var config = configUtils.getConfig();
        if (null != svcCatalog) {
            for (var key in svcCatalog) {
                if (null == firstRegion) {
                    firstRegion = key;
                }
                req.session.serviceCatalog[key] = svcCatalog[key];
            }
        }
        var mappedObjs = null;
        if (-1 != global.keystoneServiceListByProject.indexOf(type)) {
            var domProject = req.cookies.domain + ':' + req.cookies.project;
            mappedObjs =
                commonUtils.getValueByJsonPath(svcCatalog, regionName + ';' +
                                               domProject + ';' + type +
                                               ';maps', null);
        } else {
            mappedObjs =
                commonUtils.getValueByJsonPath(svcCatalog, regionName + ';' + type +
                                               ';maps', null);
        }
        if ((null == mappedObjs) && (global.service.MAINSEREVR == reqBy)) {
            /* We did not find this region in the service catalog */
            var secureCookieStr = (false == config.insecure_access) ? "; secure"
                : "";
            if (global.REGION_ALL != regionCookie) {
                req.res.setHeader('Set-Cookie', 'region=' +  firstRegion +
                                '; expires=Sun, 17 Jan 2038 00:00:00 UTC; path=/'
                                + secureCookieStr);
            }
            callback(null, null, redirectToLogout);
            return;
        }
        callback(mappedObjs, regionName);
    });
}

/* Function: getApiVersion
    Get the next available version from suppVerList out of verList starting from
    index with api type as apiType
    verList is the return value from getServiceAPIVersionByReqObj()
 */
function getApiVersion (suppVerList, verList, index, fallbackIndex, apiType)
{
    var ip = null;
    var port = null;
    var config = configUtils.getConfig();
    var endPtFromConfig = config.serviceEndPointFromConfig;

    try {
        var verCnt = verList.length;
        var suppVerCnt = suppVerList.length;
    } catch(e) {
        return null;
    }
    for (var i = index; i < verCnt; i++) {
        for (var j = 0; j < suppVerCnt; j++) {
            try {
                if (verList[i]['version'] != suppVerList[j]) {
                    continue;
                } else {
                    return {'version': verList[i]['version'], 'index': i,
                            'protocol': verList[i]['protocol'],
                            'ip': verList[i]['ip'], 'port': verList[i]['port'],
                            'fallbackIndex': -1};
                }
            } catch(e) {
                continue;
            }
        }
    }
    /* We are done with all versions in catalog, so now fall back to next
     * available supported list
     */
    for (var i = fallbackIndex; i >= 0; i--) {
        for (var j = 0; j < verCnt; j++) {
            if (suppVerList[i] != verList[j]) {
                /* Put index verCnt, such that next time, it does not fall into
                 * earlier loop
                 */
                return {'version': suppVerList[i], 'index': verCnt,
                        'protocol': verList[j]['protocol'],
                        'ip': verList[j]['ip'],
                        'port': verList[j]['port'], 'fallbackIndex': i};
            }
        }
    }
    return null;
}

function getPublicUrlByRegionName (regionname, serviceName, req)
{
    if (false == authApi.isMultiRegionSupported()) {
        return null;
    }
    if (true == authApi.isRegionListFromConfig()) {
        var pubUrl = null;
        var config = configUtils.getConfig();
        if (null == config.regions) {
            return null;
        }
        for (var region in config.regions) {
            if (regionname == region) {
                switch (serviceName) {
                case global.SERVICE_ENDPT_TYPE_IDENTITY:
                    return config.regions[region];
                default:
                    break;
                }
            }
        }
    }
    var takeUrlStr = (true == config.serviceEndPointTakePublicURL) ?
        'publicURL': 'internalURL';
    var pubUrl =
        commonUtils.getValueByJsonPath(req, 'session;serviceCatalog;' +
                                       regionname + ';' + serviceName +
                                       ';values;0;' + takeUrlStr, null,
                                       false);
    return pubUrl;
}

function shiftServiceEndpointList (req, serviceType, regionName)
{
    if (false == authApi.isMultiRegionSupported()) {
        return;
    }
    var mappedObjs =
        commonUtils.getValueByJsonPath(req,
                                       'session;serviceCatalog;' +
                                       regionName + ';' + serviceType +
                                       ';maps', null, false);
    if (null == mappedObjs) {
        logutils.logger.error('We did not get the mapped values for Service: ' +
                              serviceType + ' for region:' + regionName);
        return;
    }
    var mapObj = mappedObjs.shift();
    mappedObjs.push(mapObj);
    req['session']['serviceCatalog'][regionName][serviceType]['maps'] = mappedObjs;
}

exports.getServiceAPIVersionByReqObj = getServiceAPIVersionByReqObj;
exports.getApiVersion = getApiVersion;
exports.getIpProtoByServCatPubUrl = getIpProtoByServCatPubUrl;
exports.getServiceApiVersionObjByPubUrl = getServiceApiVersionObjByPubUrl;
exports.getPublicUrlByRegionName = getPublicUrlByRegionName;
exports.shiftServiceEndpointList = shiftServiceEndpointList;
<commit_msg>Few more changes related to auto detect config without server restart Related-bug: #1683280<commit_after>/*
 * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
 */

/**
 * This file contains utility functions for Openstack components
 */

var authApi = require('../../../common/auth.api');
var configUtils = require('../../../common/config.utils');
var httpsOp = require('../../../common/httpsoptions.api');
var logutils = require('../../../utils/log.utils');
var commonUtils = require('../../../utils/common.utils');

/* Function: getIpProtoByServCatPubUrl
    This function is used to parse the publicURL/internalURL got from keystone catalog,
    And returns protocol (http/https), IP and port of the service
    publicURL/internalURL can be any of below formats:
    http://xxx.xxx.xxx.xxx:xxxx/v2.0 and
    xxx.xxx.xxx.xxx:xxxx/v2.0 and
 */
function getIpProtoByServCatPubUrl (pubUrl)
{
    var ipAddr = null;
    var port = null;
    var reqProto = global.PROTOCOL_HTTP;
    var ipAddrStr = pubUrl, portStr = null;
    var ipIdx = -1, portIdx = -1;

    ipIdx = pubUrl.indexOf(global.HTTPS_URL);
    if (ipIdx >= 0) {
        reqProto = global.PROTOCOL_HTTPS;
        ipAddrStr = pubUrl.slice(ipIdx + (global.HTTPS_URL).length);
    }
    ipIdx = pubUrl.indexOf(global.HTTP_URL);
    if (ipIdx >= 0) {
        ipAddrStr = pubUrl.slice(ipIdx + (global.HTTP_URL).length);
    }

    /* Format is http://<ip/host>:<port>/XXXX */
    portIdx = ipAddrStr.indexOf(':');
    if (-1 != portIdx) {
        ipAddr = ipAddrStr.substr(0, portIdx);
        portStr = ipAddrStr.slice(portIdx + 1);
        portIdx = portStr.indexOf('/');
        if (-1 != portIdx) {
            port = portStr.substr(0, portIdx);
        } else {
            port = portStr;
        }
    }
    return {'ipAddr': ipAddr, 'port': port, 'protocol': reqProto};
}

function getServiceApiVersionObjByPubUrl (pubUrl, type)
{
    if (null == pubUrl) {
        return null;
    }
    var ipProtoObj = getIpProtoByServCatPubUrl(pubUrl);
    var reqProto = ipProtoObj['protocol'];
    var ipAddr = ipProtoObj['ipAddr'];
    var port = ipProtoObj['port'];
    var version = null;

    switch (type) {
    case 'compute':
    case 'volume':
        try {
            var idx = pubUrl.lastIndexOf('/');
            if (-1 == idx) {
                return null;
            }
            var str = pubUrl.substr(0, idx);
            idx = str.lastIndexOf('/');
            if (-1 == idx) {
                return null;
            }
            version = str.slice(idx + 1);
        } catch(e) {
            logutils.logger.error('volume|compute pubUrl parse error' + e);
        }
        break;
    case 'image':
    case 'identity':
        try {
            var defVer = getDfltEndPointValueByType(type, 'version');
            var protoIdx = pubUrl.indexOf('://');
            if (protoIdx >= 0) {
                pubUrl = pubUrl.slice(protoIdx + '://'.length);
            }
            var idx = pubUrl.indexOf('/');
            if (idx >= 0) {
                pubUrl = pubUrl.slice(idx + 1);
                idx = pubUrl.indexOf('/');
                if (idx >= 0) {
                    /* Format: http://localhost:9292/v1/ or
                     * localhost:9292/v1/
                     */
                    version = pubUrl.substr(0, idx);
                } else {
                    if (!pubUrl.length) {
                        /* Format: http://localhost:9292/ or
                         * localhost:9292/
                         */
                        version = defVer;
                    } else {
                        /* Format: http://localhost:9292/v1 or
                         * localhost:9292/v1
                         */
                        version = pubUrl;
                    }
                }
            } else {
                /* Format: http://localhost:9292 or localhost:9292 */
                version = defVer;
            }
        } catch(e) {
            logutils.logger.error(type +' pubUrl parse error' + e);
        }
        break;
    default:
        break;
    }
    return {version: version, ip: ipAddr, protocol: reqProto, port: port};
}

/* Function: getApiTypeByServiceType
   Maps service type to webServer Server type
 */
function getApiTypeByServiceType (servType)
{
    switch (servType) {
    case global.SERVICE_ENDPT_TYPE_COMPUTE:
        return global.label.COMPUTE_SERVER;
    case global.SERVICE_ENDPT_TYPE_IMAGE:
        return global.label.IMAGE_SERVER;
    case global.SERVICE_ENDPT_TYPE_NETWORK:
        return global.label.NETWORK_SERVER;
    case global.SERVICE_ENDPT_TYPE_IDENTITY:
        return global.label.IDENTITY_SERVER;
    case global.SERVICE_ENDPT_TYPE_VOLUME:
        return global.label.STORAGE_SERVER;
    default:
        return servType;
    }
}

/* Function: getOStackModuleApiVersion
   Get the API Version from Config File, if not specified then take default
   suppoted API Versions
 */
function getOStackModuleApiVersion (apiType)
{
    var version = httpsOp.getHttpsOptionsByAPIType(apiType, 'apiVersion');
    if (null == version) {
        switch (apiType) {
        case global.label.IMAGE_SERVER:
            return glanceApi.imageListVerList;
        case global.label.COMPUTE_SERVER:
            return novaApi.novaAPIVerList;
        default:
            return null;
        }
    }
    return version;
}

/* Function: getDfltEndPointValueByType
   Get the version etc info by end point module types
 */
function getDfltEndPointValueByType (module, type)
{
    switch (module) {
    case 'image':
        if ('version' == type) {
            return 'v1';
        }
        break;
    case 'nova':
        if ('version' == type) {
            return 'v1.1';
        }
        break;
    case 'identity':
        if ('version' == type) {
            return 'v2.0';
        }
        break;
    default:
        break;
    }
    return null;
}

/* Function: getServiceAPIVersionByReqObj
    Get openStack Module API Version, IP, Port, Protocol from
    publicURL/internalURL in keystone catalog response
 */
function getServiceAPIVersionByReqObj (req, appData, type, callback, reqBy)
{
    var redirectToLogout = true;
    var dataObjArr = [];
    var endPtList = [];
    var config = configUtils.getConfig();

    var endPtFromConfig = config.serviceEndPointFromConfig;
    if (null == endPtFromConfig) {
        endPtFromConfig = true;
    }
    if (true == endPtFromConfig) {
        if ((type ==
             authApi.getEndpointServiceType(global.DEFAULT_CONTRAIL_API_IDENTIFIER)) ||
            (type ==
             authApi.getEndpointServiceType(global.DEFAULT_CONTRAIL_ANALYTICS_IDENTIFIER))) {
            /* for opServer and apiServer, we will be getting directly from
             * apiRestApi
             */
            callback(null);
            return;
        }
        var apiType = getApiTypeByServiceType(type);
        ip = httpsOp.getHttpsOptionsByAPIType(apiType, 'ip');
        port = httpsOp.getHttpsOptionsByAPIType(apiType, 'port');
        version = getOStackModuleApiVersion(apiType);
        protocol = httpsOp.getHttpsOptionsByAPIType(apiType, 'authProtocol');
        if ((null == ip) || (null == port) || (null == version) ||
            (null == protocol)) {
            logutils.logger.error("ip/port/apiVersion/authProtocol not found in" +
                                  " config file for:" + apiType);
            callback(null);
            return;
        }
        var verLen = version.length;
        for (var i = 0; i < verLen; i++) {
            dataObjArr.push({'version': version[i], 'protocol': protocol, 'ip': ip,
                            'port': port});
        }
        if (!dataObjArr.length) {
            logutils.logger.error('apiVersion for ' + type + ' is NULL');
            callback(null);
        } else {
            dataObjArr.sort(function(a, b) {
                if (b['version'] > a['version']) {
                    return 1;
                } else if (b['version'] < a['version']) {
                    return -1;
                } else {
                    return 0;
                }
            });
            callback(dataObjArr);
        }
        return;
    }
    var regionCookie =
        commonUtils.getValueByJsonPath(req, 'cookies;region', null, false);
    if (null == regionCookie) {
        callback(null, null, redirectToLogout);
        return;
    }
    var regionName = authApi.getCurrentRegion(req);
    var reqRegion = commonUtils.getValueByJsonPath(appData, "authObj;reqRegion",
                                                   null);
    if (null != reqRegion) {
        regionName = reqRegion;
    }
    if ((null != regionName) && ('undefined' != regionName)) {
        serviceCatalog =
            commonUtils.getValueByJsonPath(req, 'session;serviceCatalog;' +
                                           regionName, null, false);
    } else {
        serviceCatalog = commonUtils.getValueByJsonPath(req,
                                                        'session;serviceCatalog',
                                                        null, false);
        if (null != serviceCatalog) {
            for (var key in serviceCatalog) {
                regionName = key;
                req.session.regionname = regionName;
                serviceCatalog = serviceCatalog[key];
                break;
            }
        }
    }
    if (null != serviceCatalog) {
        mappedObj = null;
        try {
            mappedObjs = serviceCatalog[type].maps;
        } catch(e) {
            mappedObjs = null;
        }
        if ((null != mappedObjs) && (null != mappedObjs[0])) {
            callback(mappedObjs, regionName);
            return;
        }
    }
    authApi.getServiceCatalog(req, function(accessData) {
        if ((null == accessData) || (null == accessData.serviceCatalog)) {
            callback(null, null, redirectToLogout);
            return;
        }
        var keySt = require('./keystone.api');
        var svcCatalog =
            keySt.getServiceCatalogByRegion(req, regionName, accessData);
        var firstRegion = null;
        var config = configUtils.getConfig();
        if (null != svcCatalog) {
            for (var key in svcCatalog) {
                if (null == firstRegion) {
                    firstRegion = key;
                }
                req.session.serviceCatalog[key] = svcCatalog[key];
            }
        }
        var mappedObjs = null;
        if (-1 != global.keystoneServiceListByProject.indexOf(type)) {
            var domProject = req.cookies.domain + ':' + req.cookies.project;
            mappedObjs =
                commonUtils.getValueByJsonPath(svcCatalog, regionName + ';' +
                                               domProject + ';' + type +
                                               ';maps', null);
        } else {
            mappedObjs =
                commonUtils.getValueByJsonPath(svcCatalog, regionName + ';' + type +
                                               ';maps', null);
        }
        if ((null == mappedObjs) && (global.service.MAINSEREVR == reqBy)) {
            /* We did not find this region in the service catalog */
            var secureCookieStr = (false == config.insecure_access) ? "; secure"
                : "";
            if (global.REGION_ALL != regionCookie) {
                req.res.setHeader('Set-Cookie', 'region=' +  firstRegion +
                                '; expires=Sun, 17 Jan 2038 00:00:00 UTC; path=/'
                                + secureCookieStr);
            }
            callback(null, null, redirectToLogout);
            return;
        }
        callback(mappedObjs, regionName);
    });
}

/* Function: getApiVersion
    Get the next available version from suppVerList out of verList starting from
    index with api type as apiType
    verList is the return value from getServiceAPIVersionByReqObj()
 */
function getApiVersion (suppVerList, verList, index, fallbackIndex, apiType)
{
    var ip = null;
    var port = null;
    var config = configUtils.getConfig();
    var endPtFromConfig = config.serviceEndPointFromConfig;

    try {
        var verCnt = verList.length;
        var suppVerCnt = suppVerList.length;
    } catch(e) {
        return null;
    }
    for (var i = index; i < verCnt; i++) {
        for (var j = 0; j < suppVerCnt; j++) {
            try {
                if (verList[i]['version'] != suppVerList[j]) {
                    continue;
                } else {
                    return {'version': verList[i]['version'], 'index': i,
                            'protocol': verList[i]['protocol'],
                            'ip': verList[i]['ip'], 'port': verList[i]['port'],
                            'fallbackIndex': -1};
                }
            } catch(e) {
                continue;
            }
        }
    }
    /* We are done with all versions in catalog, so now fall back to next
     * available supported list
     */
    for (var i = fallbackIndex; i >= 0; i--) {
        for (var j = 0; j < verCnt; j++) {
            if (suppVerList[i] != verList[j]) {
                /* Put index verCnt, such that next time, it does not fall into
                 * earlier loop
                 */
                return {'version': suppVerList[i], 'index': verCnt,
                        'protocol': verList[j]['protocol'],
                        'ip': verList[j]['ip'],
                        'port': verList[j]['port'], 'fallbackIndex': i};
            }
        }
    }
    return null;
}

function getPublicUrlByRegionName (regionname, serviceName, req)
{
    var config = configUtils.getConfig();
    if (false == authApi.isMultiRegionSupported()) {
        return null;
    }
    if (true == authApi.isRegionListFromConfig()) {
        var pubUrl = null;
        if (null == config.regions) {
            return null;
        }
        for (var region in config.regions) {
            if (regionname == region) {
                switch (serviceName) {
                case global.SERVICE_ENDPT_TYPE_IDENTITY:
                    return config.regions[region];
                default:
                    break;
                }
            }
        }
    }
    var takeUrlStr = (true == config.serviceEndPointTakePublicURL) ?
        'publicURL': 'internalURL';
    var pubUrl =
        commonUtils.getValueByJsonPath(req, 'session;serviceCatalog;' +
                                       regionname + ';' + serviceName +
                                       ';values;0;' + takeUrlStr, null,
                                       false);
    return pubUrl;
}

function shiftServiceEndpointList (req, serviceType, regionName)
{
    if (false == authApi.isMultiRegionSupported()) {
        return;
    }
    var mappedObjs =
        commonUtils.getValueByJsonPath(req,
                                       'session;serviceCatalog;' +
                                       regionName + ';' + serviceType +
                                       ';maps', null, false);
    if (null == mappedObjs) {
        logutils.logger.error('We did not get the mapped values for Service: ' +
                              serviceType + ' for region:' + regionName);
        return;
    }
    var mapObj = mappedObjs.shift();
    mappedObjs.push(mapObj);
    req['session']['serviceCatalog'][regionName][serviceType]['maps'] = mappedObjs;
}

exports.getServiceAPIVersionByReqObj = getServiceAPIVersionByReqObj;
exports.getApiVersion = getApiVersion;
exports.getIpProtoByServCatPubUrl = getIpProtoByServCatPubUrl;
exports.getServiceApiVersionObjByPubUrl = getServiceApiVersionObjByPubUrl;
exports.getPublicUrlByRegionName = getPublicUrlByRegionName;
exports.shiftServiceEndpointList = shiftServiceEndpointList;
<|endoftext|>


<commit_before>"use strict";

module.exports = function ($stateProvider, $urlRouterProvider, $locationProvider, webStructure) {
	var self = this;

	// configure html5mode for URLs (no #)
	$locationProvider.html5Mode({ enabled: true });

	// configure default route
	$urlRouterProvider.when("", "/home");
	$urlRouterProvider.when("/", "/home");
	$urlRouterProvider.otherwise("/error/404");

	// configure application states
	$stateProvider.state("main", { abstract: true, templateUrl: "pages/main/template.html", controller: "MainController as ctrl" })
		.state("main.error", {
			abstract: true,
			url: "/error",
			templateUrl: "pages/main/error/template.html",
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.ERROR", parent: "main.home" }
		})
		.state("main.error.404", {
			url: "/404",
			templateUrl: "pages/main/error/404.html",
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.ERROR.404", parent: "main.error" }
		})
		.state("main.auth", {
			abstract: true,
			url: "/auth",
			templateUrl: "pages/main/auth/template.html",
			ncyBreadcrumb: { parent: "main.home" }
		})
		.state("main.auth.login", {
			url: "/login",
			templateUrl: "pages/main/auth/login.html",
			controller: "AuthLoginController as ctrl",
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.AUTH.LOGIN", parent: "main.auth" }
		})
		.state("main.auth.logout", {
			url: "/logout",
			controller: [
				"$rootScope", "$auth", "$state", "Notification",
				function ($rootScope, $auth, $state, Notification) {
					$auth.logout().then(function () {
						// Flip authenticated to false so that we no longer
						// show UI elements dependant on the user being logged in
						$rootScope.authenticated = false;
						$rootScope.currentUser = {};

						Notification.success({
							title: "APP.AUTH.LOGOUT.NOTIFICATION.HEADER",
							message: "APP.AUTH.LOGOUT.NOTIFICATION.MESSAGE.SUCCESS"
						});
						$state.go("main.home");
					});
				}
			]
		})
		.state("main.auth.register", {
			url: "/register",
			templateUrl: "pages/main/auth/registration.html",
			controller: "AuthRegistrationController as ctrl",
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.AUTH.REGISTER", parent: "main.auth" }
		})
		.state("main.home", {
			url: "/home",
			templateUrl: "pages/main/website/home.html",
			controller: "WebsiteHomeController as ctrl",
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.HOME" }
		})
		.state("main.news", {
			url: "/news/:file",
			templateUrl: "pages/main/website/news.html",
			controller: "WebsiteListfilesController as ctrl",
			params: { file: null },
			resolve: {
				files: [
					"news",
					function (news) {
						return news;
					}
				],
				currentFile: [
					"$q", "$timeout", "$state", "$stateParams", "WebsiteService", "files",
					function ($q, $timeout, $state, $stateParams, WebsiteService, files) {
						var deferred = $q.defer();

						$timeout (function () {
							if ($stateParams.file === null)
							{
								$state.go("main.news", {
									file: files.filter(function (elem) {
											   return elem.type === "file";
										   })[0]
										      .slug
								});
								deferred.reject();
							}
							else
							{
								var filtered = files.filter(function (elem) {
									return (elem.type === "file" && elem.slug === $stateParams.file);
								});
								if (filtered.length === 0)
								{
									$state.go("main.news", { file: files[0].slug });
									deferred.reject();
								}
								else
								{
									WebsiteService.loadFile(filtered[0].file).then(function (data) {
										var file = filtered[0];
										file.content = data;
										deferred.resolve(file);
									});
								}
							}
						});

						return deferred.promise;
					}
				]
			},
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.NEWS", parent: "main.home" }
		})
		.state("main.dyn", { abstract: true, template: "

", ncyBreadcrumb: { parent: "main.home" } })
		.state("main.account", {
			url: "/account",
			templateUrl: "pages/main/users/details.html",
			controller: "UserDetailsController as ctrl",
			params: { username: "", useAuthUser: true },
			resolve: {
				user: [
					"$stateParams", "UserService",
					function ($stateParams, UserService) {
						return UserService.get("", $stateParams.useAuthUser);
					}
				]
			},
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.ACCOUNT", parent: "main.home" }
		})
		.state("main.entries", {
			abstract: true,
			url: "/entries",
			templateUrl: "pages/main/entries/template.html",
			ncyBreadcrumb: { parent: "main.home" }
		})
		.state("main.entries.search", {
			url: "/search",
			templateUrl: "pages/main/entries/search.html",
			controller: "EntrySearchController as ctrl",
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.ENTRIES.SEARCH", parent: "main.entries" }
		})
		.state("main.entries.details", {
			url: "/details/:entry",
			templateUrl: "pages/main/entries/details.html",
			controller: "EntryDetailsController as ctrl",
			params: { entry: "" },
			resolve: {
				entry: [
					"$stateParams", "EntryService",
					function ($stateParams, EntryService) {
						return EntryService.get($stateParams.entry);
					}
				]
			},
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.ENTRIES.DETAILS", parent: "main.entries.search" }
		})
		.state("main.entries.edit", {
			url: "/edit/:entry",
			templateUrl: "pages/main/entries/edit.html",
			controller: "EntryEditController as ctrl",
			params: { entry: "" },
			resolve: {
				formats: [
					"EntryService",
					function (EntryService) {
						return EntryService.loadAvailableFormats();
					}
				],
				typeaheads: [
					"EntryService",
					function (EntryService) {
						return EntryService.loadAvailableTypeaheads();
					}
				],
				entry: [
					"$stateParams", "EntryService",
					function ($stateParams, EntryService) {
						return EntryService.get($stateParams.entry);
					}
				],
				hasPermission: [
					"$rootScope", "entry", "$q",
					function ($rootScope, entry, $q) {
						var deferred = $q.defer();

						if ($rootScope.currentUser && ($rootScope.currentUser.rank >= 50 ||
									       $rootScope.currentUser.username === entry.meta.author))
						{
							deferred.resolve(true);
						}
						else
						{
							deferred.reject(false);
						}

						return deferred.promise;
					}
				]
			},
			data: {
				// rank: 50	// this check has to be done by the resolver as well
			},
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.ENTRIES.EDIT", parent: "main.entries.details" }
		})
		.state("main.entries.create", {
			url: "/create",
			templateUrl: "pages/main/entries/create.html",
			controller: "EntryCreateController as ctrl",
			resolve: {
				formats: [
					"EntryService",
					function (EntryService) {
						return EntryService.loadAvailableFormats();
					}
				],
				typeaheads: [
					"EntryService",
					function (EntryService) {
						return EntryService.loadAvailableTypeaheads();
					}
				]
			},
			data: { rank: 10 },
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.ENTRIES.CREATE", parent: "main.entries" }
		})
		.state("main.users", {
			abstract: true,
			url: "/users",
			templateUrl: "pages/main/users/template.html",
			ncyBreadcrumb: { parent: "main.home" }
		})
		.state("main.users.search", {
			url: "/search",
			templateUrl: "pages/main/users/search.html",
			controller: "UserSearchController as ctrl",
			data: { rank: 100 },
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.USERS.SEARCH", parent: "main.users" }
		})
		.state("main.users.details", {
			url: "/details/:username",
			templateUrl: "pages/main/users/details.html",
			controller: "UserDetailsController as ctrl",
			params: { username: "", useAuthUser: false },
			data: { rank: 100 },
			resolve: {
				user: [
					"$stateParams", "UserService",
					function ($stateParams, UserService) {
						return UserService.get($stateParams.username);
					}
				]
			},
			ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.USERS.DETAILS", parent: "main.users" }
		});

	/* CONFIGURE DYNAMIC PAGES */

	// read the structure file and handle entries
	webStructure.forEach(function (entry) {
		consumeEntry (entry);
	});

	// main parse function
	function consumeEntry (entry)
	{
		switch (entry.type)
		{
		case "submenu":
			entry.children.forEach(function (child) {
				consumeEntry (child);
			});
			break;
		case "listfiles":
			$stateProvider.state("main.dyn." + entry.ref, {
				url: "/" + entry.ref + "/:file",
				templateUrl: "pages/main/website/listfiles.html",
				controller: "WebsiteListfilesController as ctrl",
				params: { file: null },
				data: { name: entry.name, ref: entry.ref },
				resolve: {
					files: [function () {
						return entry.children;
					}],
					currentFile: [
						"$q", "$timeout", "$state", "$stateParams", "WebsiteService", "files",
						function ($q, $timeout, $state, $stateParams, WebsiteService, files) {
							var deferred = $q.defer();

							$timeout (function () {
								if ($stateParams.file === null)
								{
									$state.go("main.dyn." + entry.ref, {
										file: files.filter(function (elem) {
												   return elem.type === "file";
											   })[0]
											      .slug
									});
									deferred.reject();
								}
								else
								{
									var filtered = files.filter(function (elem) {
										return (elem.type === "file" &&
											elem.slug === $stateParams.file);
									});
									if (filtered.length === 0)
									{
										$state.go("main.dyn." + entry.ref, {
											file: files.filter(function (elem) {
													   return elem.type === "file";
												   })[0]
												      .slug
										});
										deferred.reject();
									}
									else
									{
										WebsiteService.loadFile(filtered[0].options.path)
											.then(function (data) {
												var file = filtered[0];
												file.content = data;
												deferred.resolve(file);
											});
									}
								}
							});

							return deferred.promise;
						}
					]
				},
				ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.DYN." + entry.ref.toUpperCase(), parent: "main.dyn" }
			});
			break;
		default:
			break;
		}
	}
};
<commit_msg>Restyled by prettier<commit_after>"use strict";

module.exports = function(
  $stateProvider,
  $urlRouterProvider,
  $locationProvider,
  webStructure
) {
  var self = this;

  // configure html5mode for URLs (no #)
  $locationProvider.html5Mode({ enabled: true });

  // configure default route
  $urlRouterProvider.when("", "/home");
  $urlRouterProvider.when("/", "/home");
  $urlRouterProvider.otherwise("/error/404");

  // configure application states
  $stateProvider
    .state("main", {
      abstract: true,
      templateUrl: "pages/main/template.html",
      controller: "MainController as ctrl"
    })
    .state("main.error", {
      abstract: true,
      url: "/error",
      templateUrl: "pages/main/error/template.html",
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.ERROR",
        parent: "main.home"
      }
    })
    .state("main.error.404", {
      url: "/404",
      templateUrl: "pages/main/error/404.html",
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.ERROR.404",
        parent: "main.error"
      }
    })
    .state("main.auth", {
      abstract: true,
      url: "/auth",
      templateUrl: "pages/main/auth/template.html",
      ncyBreadcrumb: { parent: "main.home" }
    })
    .state("main.auth.login", {
      url: "/login",
      templateUrl: "pages/main/auth/login.html",
      controller: "AuthLoginController as ctrl",
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.AUTH.LOGIN",
        parent: "main.auth"
      }
    })
    .state("main.auth.logout", {
      url: "/logout",
      controller: [
        "$rootScope",
        "$auth",
        "$state",
        "Notification",
        function($rootScope, $auth, $state, Notification) {
          $auth.logout().then(function() {
            // Flip authenticated to false so that we no longer
            // show UI elements dependant on the user being logged in
            $rootScope.authenticated = false;
            $rootScope.currentUser = {};

            Notification.success({
              title: "APP.AUTH.LOGOUT.NOTIFICATION.HEADER",
              message: "APP.AUTH.LOGOUT.NOTIFICATION.MESSAGE.SUCCESS"
            });
            $state.go("main.home");
          });
        }
      ]
    })
    .state("main.auth.register", {
      url: "/register",
      templateUrl: "pages/main/auth/registration.html",
      controller: "AuthRegistrationController as ctrl",
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.AUTH.REGISTER",
        parent: "main.auth"
      }
    })
    .state("main.home", {
      url: "/home",
      templateUrl: "pages/main/website/home.html",
      controller: "WebsiteHomeController as ctrl",
      ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.HOME" }
    })
    .state("main.news", {
      url: "/news/:file",
      templateUrl: "pages/main/website/news.html",
      controller: "WebsiteListfilesController as ctrl",
      params: { file: null },
      resolve: {
        files: [
          "news",
          function(news) {
            return news;
          }
        ],
        currentFile: [
          "$q",
          "$timeout",
          "$state",
          "$stateParams",
          "WebsiteService",
          "files",
          function($q, $timeout, $state, $stateParams, WebsiteService, files) {
            var deferred = $q.defer();

            $timeout(function() {
              if ($stateParams.file === null) {
                $state.go("main.news", {
                  file: files.filter(function(elem) {
                    return elem.type === "file";
                  })[0].slug
                });
                deferred.reject();
              } else {
                var filtered = files.filter(function(elem) {
                  return (
                    elem.type === "file" && elem.slug === $stateParams.file
                  );
                });
                if (filtered.length === 0) {
                  $state.go("main.news", { file: files[0].slug });
                  deferred.reject();
                } else {
                  WebsiteService.loadFile(filtered[0].file).then(function(
                    data
                  ) {
                    var file = filtered[0];
                    file.content = data;
                    deferred.resolve(file);
                  });
                }
              }
            });

            return deferred.promise;
          }
        ]
      },
      ncyBreadcrumb: { label: "APP.BREADCRUMBS.MAIN.NEWS", parent: "main.home" }
    })
    .state("main.dyn", {
      abstract: true,
      template: "

",
      ncyBreadcrumb: { parent: "main.home" }
    })
    .state("main.account", {
      url: "/account",
      templateUrl: "pages/main/users/details.html",
      controller: "UserDetailsController as ctrl",
      params: { username: "", useAuthUser: true },
      resolve: {
        user: [
          "$stateParams",
          "UserService",
          function($stateParams, UserService) {
            return UserService.get("", $stateParams.useAuthUser);
          }
        ]
      },
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.ACCOUNT",
        parent: "main.home"
      }
    })
    .state("main.entries", {
      abstract: true,
      url: "/entries",
      templateUrl: "pages/main/entries/template.html",
      ncyBreadcrumb: { parent: "main.home" }
    })
    .state("main.entries.search", {
      url: "/search",
      templateUrl: "pages/main/entries/search.html",
      controller: "EntrySearchController as ctrl",
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.ENTRIES.SEARCH",
        parent: "main.entries"
      }
    })
    .state("main.entries.details", {
      url: "/details/:entry",
      templateUrl: "pages/main/entries/details.html",
      controller: "EntryDetailsController as ctrl",
      params: { entry: "" },
      resolve: {
        entry: [
          "$stateParams",
          "EntryService",
          function($stateParams, EntryService) {
            return EntryService.get($stateParams.entry);
          }
        ]
      },
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.ENTRIES.DETAILS",
        parent: "main.entries.search"
      }
    })
    .state("main.entries.edit", {
      url: "/edit/:entry",
      templateUrl: "pages/main/entries/edit.html",
      controller: "EntryEditController as ctrl",
      params: { entry: "" },
      resolve: {
        formats: [
          "EntryService",
          function(EntryService) {
            return EntryService.loadAvailableFormats();
          }
        ],
        typeaheads: [
          "EntryService",
          function(EntryService) {
            return EntryService.loadAvailableTypeaheads();
          }
        ],
        entry: [
          "$stateParams",
          "EntryService",
          function($stateParams, EntryService) {
            return EntryService.get($stateParams.entry);
          }
        ],
        hasPermission: [
          "$rootScope",
          "entry",
          "$q",
          function($rootScope, entry, $q) {
            var deferred = $q.defer();

            if (
              $rootScope.currentUser &&
              ($rootScope.currentUser.rank >= 50 ||
                $rootScope.currentUser.username === entry.meta.author)
            ) {
              deferred.resolve(true);
            } else {
              deferred.reject(false);
            }

            return deferred.promise;
          }
        ]
      },
      data: {
        // rank: 50	// this check has to be done by the resolver as well
      },
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.ENTRIES.EDIT",
        parent: "main.entries.details"
      }
    })
    .state("main.entries.create", {
      url: "/create",
      templateUrl: "pages/main/entries/create.html",
      controller: "EntryCreateController as ctrl",
      resolve: {
        formats: [
          "EntryService",
          function(EntryService) {
            return EntryService.loadAvailableFormats();
          }
        ],
        typeaheads: [
          "EntryService",
          function(EntryService) {
            return EntryService.loadAvailableTypeaheads();
          }
        ]
      },
      data: { rank: 10 },
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.ENTRIES.CREATE",
        parent: "main.entries"
      }
    })
    .state("main.users", {
      abstract: true,
      url: "/users",
      templateUrl: "pages/main/users/template.html",
      ncyBreadcrumb: { parent: "main.home" }
    })
    .state("main.users.search", {
      url: "/search",
      templateUrl: "pages/main/users/search.html",
      controller: "UserSearchController as ctrl",
      data: { rank: 100 },
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.USERS.SEARCH",
        parent: "main.users"
      }
    })
    .state("main.users.details", {
      url: "/details/:username",
      templateUrl: "pages/main/users/details.html",
      controller: "UserDetailsController as ctrl",
      params: { username: "", useAuthUser: false },
      data: { rank: 100 },
      resolve: {
        user: [
          "$stateParams",
          "UserService",
          function($stateParams, UserService) {
            return UserService.get($stateParams.username);
          }
        ]
      },
      ncyBreadcrumb: {
        label: "APP.BREADCRUMBS.MAIN.USERS.DETAILS",
        parent: "main.users"
      }
    });

  /* CONFIGURE DYNAMIC PAGES */

  // read the structure file and handle entries
  webStructure.forEach(function(entry) {
    consumeEntry(entry);
  });

  // main parse function
  function consumeEntry(entry) {
    switch (entry.type) {
      case "submenu":
        entry.children.forEach(function(child) {
          consumeEntry(child);
        });
        break;
      case "listfiles":
        $stateProvider.state("main.dyn." + entry.ref, {
          url: "/" + entry.ref + "/:file",
          templateUrl: "pages/main/website/listfiles.html",
          controller: "WebsiteListfilesController as ctrl",
          params: { file: null },
          data: { name: entry.name, ref: entry.ref },
          resolve: {
            files: [
              function() {
                return entry.children;
              }
            ],
            currentFile: [
              "$q",
              "$timeout",
              "$state",
              "$stateParams",
              "WebsiteService",
              "files",
              function(
                $q,
                $timeout,
                $state,
                $stateParams,
                WebsiteService,
                files
              ) {
                var deferred = $q.defer();

                $timeout(function() {
                  if ($stateParams.file === null) {
                    $state.go("main.dyn." + entry.ref, {
                      file: files.filter(function(elem) {
                        return elem.type === "file";
                      })[0].slug
                    });
                    deferred.reject();
                  } else {
                    var filtered = files.filter(function(elem) {
                      return (
                        elem.type === "file" && elem.slug === $stateParams.file
                      );
                    });
                    if (filtered.length === 0) {
                      $state.go("main.dyn." + entry.ref, {
                        file: files.filter(function(elem) {
                          return elem.type === "file";
                        })[0].slug
                      });
                      deferred.reject();
                    } else {
                      WebsiteService.loadFile(filtered[0].options.path).then(
                        function(data) {
                          var file = filtered[0];
                          file.content = data;
                          deferred.resolve(file);
                        }
                      );
                    }
                  }
                });

                return deferred.promise;
              }
            ]
          },
          ncyBreadcrumb: {
            label: "APP.BREADCRUMBS.MAIN.DYN." + entry.ref.toUpperCase(),
            parent: "main.dyn"
          }
        });
        break;
      default:
        break;
    }
  }
};
<|endoftext|>


<commit_before>//set main namespace
goog.provide('m');

goog.require('m.Entity');
goog.require('m.Player');
goog.require('m.Wall');
goog.require('m.Box');
goog.require('m.Button');
goog.require('m.PlayerButton');
goog.require('m.BoxButton');
goog.require('m.Platform');
goog.require('m.Target');
goog.require('m.DoorTarget');
goog.require('m.TrapTarget');
goog.require('m.DeathZone');
goog.require('m.ManualAnimation');

goog.require('box2d.BodyDef');
goog.require('box2d.BoxDef');
goog.require('box2d.CircleDef');
goog.require('box2d.CircleShape');
goog.require('box2d.PolyDef');
goog.require('box2d.Vec2');
goog.require('box2d.JointDef');
goog.require('box2d.MouseJointDef');
goog.require('box2d.World');

goog.require('lime.Director');
goog.require('lime.Scene');
goog.require('lime.Layer');
goog.require('lime.Circle');
goog.require('lime.RoundedRect');
goog.require('lime.Label');
goog.require('lime.animation.Spawn');
goog.require('lime.animation.FadeTo');
goog.require('lime.animation.ScaleTo');
goog.require('lime.animation.MoveTo');

goog.require('lime.parser.TMX');

// Globals
var tilesSize = 32;
var layers, references = [], buttons = [], targets = {}, bodiesToRemove = [];
var world;
var player;
var startPosition = {x: 4, y: 39};

// entrypoint
m.start = function() {
	function load_tmx(tmx) {
		for ( var i=0; i<tmx.layers.length; i++ ) {
			if ( layers[ tmx.layers[i].name ] ) {
				layer = layers[ tmx.layers[i].name ];
				layer.setPosition( tmx.layers[i].px, tmx.layers[i].py);

				tmx.layers[i].tiles.forEach(function(tileInfos) {
					if (tileInfos.tile.properties instanceof Array) {
						tileInfos.tile.properties = tmx_tile_parse_property(tileInfos.tile);
					}

					var type;
					switch (tileInfos.tile.properties.type) {

						case 'triggerWorld' :
							type = 'BoxButton';
							break;

						case 'triggerPlayer':
							type = 'PlayerButton';
							break;

						case 'door':
							type = 'DoorTarget';
							break;

						case 'trap':
							type = 'TrapTarget';
							break;

						case 'mortal':
							type = 'DeathZone';
							break;

                        default:
                            type = 'Wall';
                    }
                    if (tileInfos.tile.properties.type != 'ignore') {
                    	new m[type](tileInfos);
                    }
				});
			}
		}
		for ( var key in layers ) {
			scene.appendChild(layers[ key ]);
		}
	}

	function tmx_tile_parse_property(tile) {

		var values = {};
		if (tile.properties.length > 0) {
			tile.properties.forEach(function(prop) {
				values[prop.name] = prop.value;
			});
		}
		return values;
	}

	function tmx_tile_get_property(tile, name) {
		var value = null;
		tile.properties.forEach(function(prop) {
			if (prop.name == name) {
				value = prop.value;
			}
		});
		return value;
	}

	// World
	var gravity = new box2d.Vec2(0, 1500);
	var bounds = new box2d.AABB();
	bounds.minVertex.Set(0, 0);
	bounds.maxVertex.Set(1700,1700);
	world = new box2d.World(bounds, gravity, false);

	var director = new lime.Director(document.body,640,480);
	var scene = new lime.Scene();

	// TMX
	var tmx = new lime.parser.TMX('resources/test-area01.tmx');
	layers = {
		background: new lime.Layer().setPosition(0,-1000),
		walls: new lime.Layer().setPosition(0,-1000),
		decorations: new lime.Layer().setPosition(0, -1000),
		objects: new lime.Layer().setPosition(0,-1000),
		foreground: new lime.Layer().setPosition(0,-1000)
	};
	load_tmx(tmx);

   	// Level

	player = new m.Player(startPosition);
	//new m.Box({x: 17 * tilesSize, y: 2 * tilesSize});
	//new m.PlayerButton({x:5, y: 12});
	//new m.Platform({x: 100, y: 200});
	//new m.Door({x:7, y: 11, tile : { properties : {} } });
	//new m.Trap({x:9, y: 12, tile : { properties : {} } });

   	// Initialization
   	lime.scheduleManager.schedule(function(dt) {
		if(dt>100) dt=100; // long delays(after pause) cause false collisions
		player.beforePhysics();
		world.Step(dt / 1000, 3);
		for (var i = 0; i < references.length; i++) {
			references[i].update(dt);
		}
	},this);
	director.makeMobileWebAppCapable();
	director.replaceScene(scene);
}

//this is required for outside access after code is compiled in ADVANCED_COMPILATIONS mode
goog.exportSymbol('m.start', m.start);
<commit_msg>Ajout des objets et bug des box<commit_after>//set main namespace
goog.provide('m');

goog.require('m.Entity');
goog.require('m.Player');
goog.require('m.Wall');
goog.require('m.Box');
goog.require('m.Button');
goog.require('m.PlayerButton');
goog.require('m.BoxButton');
goog.require('m.Platform');
goog.require('m.Target');
goog.require('m.DoorTarget');
goog.require('m.TrapTarget');
goog.require('m.DeathZone');
goog.require('m.ManualAnimation');

goog.require('box2d.BodyDef');
goog.require('box2d.BoxDef');
goog.require('box2d.CircleDef');
goog.require('box2d.CircleShape');
goog.require('box2d.PolyDef');
goog.require('box2d.Vec2');
goog.require('box2d.JointDef');
goog.require('box2d.MouseJointDef');
goog.require('box2d.World');

goog.require('lime.Director');
goog.require('lime.Scene');
goog.require('lime.Layer');
goog.require('lime.Circle');
goog.require('lime.RoundedRect');
goog.require('lime.Label');
goog.require('lime.animation.Spawn');
goog.require('lime.animation.FadeTo');
goog.require('lime.animation.ScaleTo');
goog.require('lime.animation.MoveTo');

goog.require('lime.parser.TMX');

// Globals
var tilesSize = 32;
var layers, references = [], buttons = [], targets = {}, bodiesToRemove = [];
var world;
var player;
var startPosition = {x: 4, y: 4};

// entrypoint
m.start = function() {
	function load_tmx(tmx) {
        console.log(tmx);
		for ( var i=0; i<tmx.layers.length; i++ ) {
			if ( layers[ tmx.layers[i].name ] ) {
				layer = layers[ tmx.layers[i].name ];
				layer.setPosition( tmx.layers[i].px, tmx.layers[i].py);

				tmx.layers[i].tiles.forEach(function(tileInfos) {
                    add_tile(tileInfos);
				});
			}
		}
        for (var i=0; i<tmx.objects.length; i++) {
            var obj = tmx.objects[i];
            var tile;
            if (obj.tile) {
                tile = obj.tile;
            } else {
                tile = {
                    properties : obj.properties
                }
            }
            add_tile({
                x : obj.px,
                y : obj.py,
                tile : tile
            });
        }
		for ( var key in layers ) {
			scene.appendChild(layers[ key ]);
		}
	}

    function add_tile(tileInfos) {

        if (tileInfos.tile.properties instanceof Array) {
            tileInfos.tile.properties = tmx_tile_parse_property(tileInfos.tile);
            if (tileInfos.tile.properties.type == 'box') {
                tileInfos.tile.x *= tileInfos.x;
                tileInfos.tile.y *= tileInfos.y;
                tileInfos.tile.px = tileInfos.x * tilesSize;
                tileInfos.tile.py = tileInfos.y * tilesSize;
                tileInfos.x = tileInfos.tile.px;
                tileInfos.y = tileInfos.tile.py;
            }
        }

        var type;
        switch (tileInfos.tile.properties.type) {

            case 'triggerWorld' :
                type = 'BoxButton';
                break;

            case 'triggerPlayer':
                type = 'PlayerButton';
                break;

            case 'door':
                type = 'DoorTarget';
                break;

            case 'trap':
                type = 'TrapTarget';
                break;

            case 'mortal':
                type = 'DeathZone';
                break;

            case 'box':
                type = 'Box';
                break;

            case 'vertical':
            case 'horizontal':
                type = 'Platform';
                break;

            default:
                type = 'Wall';
        }
        if (tileInfos.tile.properties.type != 'ignore') {
            new m[type](tileInfos);
        }
    }

	function tmx_tile_parse_property(tile) {

		var values = {};
		if (tile.properties.length > 0) {
			tile.properties.forEach(function(prop) {
				values[prop.name] = prop.value;
			});
		}
		return values;
	}

	function tmx_tile_get_property(tile, name) {
		var value = null;
		tile.properties.forEach(function(prop) {
			if (prop.name == name) {
				value = prop.value;
			}
		});
		return value;
	}

	// World
	var gravity = new box2d.Vec2(0, 1500);
	var bounds = new box2d.AABB();
	bounds.minVertex.Set(0, 0);
	bounds.maxVertex.Set(1700,1700);
	world = new box2d.World(bounds, gravity, false);

	var director = new lime.Director(document.body,640,480);
	var scene = new lime.Scene();

	// TMX
	var tmx = new lime.parser.TMX('resources/test-area-test.tmx');
	layers = {
		background: new lime.Layer().setPosition(0,0),
		walls: new lime.Layer().setPosition(0,0),
		decorations: new lime.Layer().setPosition(0, 0),
		objects: new lime.Layer().setPosition(0,0),
		foreground: new lime.Layer().setPosition(0,0)
	};
	load_tmx(tmx);

   	// Level

	player = new m.Player(startPosition);
	//new m.Box({x: 17 * tilesSize, y: 2 * tilesSize});
	//new m.PlayerButton({x:5, y: 12});
	//new m.Platform({x: 100, y: 200});
	//new m.Door({x:7, y: 11, tile : { properties : {} } });
	//new m.Trap({x:9, y: 12, tile : { properties : {} } });

   	// Initialization
   	lime.scheduleManager.schedule(function(dt) {
		if(dt>100) dt=100; // long delays(after pause) cause false collisions
		player.beforePhysics();
		world.Step(dt / 1000, 3);
		for (var i = 0; i < references.length; i++) {
			references[i].update(dt);
		}
	},this);
	director.makeMobileWebAppCapable();
	director.replaceScene(scene);
}

//this is required for outside access after code is compiled in ADVANCED_COMPILATIONS mode
goog.exportSymbol('m.start', m.start);
<|endoftext|>


<commit_before>alert("Hola mundo");
<commit_msg>Modificación del texto original <commit_after>alert("Editado");
<|endoftext|>