<commit_before>(function(env) {

    var ddg_spice_flights = {

        path: "/js/spice/flights",
        id: 'route',

        // store the user's airline and city search information
        queriedAirlines: null,
        sourceCity: null,
        destinationCity: null,

        // define some static variables for callback and helpers
        MILLIS_PER_MIN: 60000,
        MILLIS_PER_HOUR: this.MILLIS_PER_MIN * 60,
        STATUS: {
            "S": "Scheduled",
            "A": "In the air",
            "U": "Unknown status",
            "R": "Redirected flight",
            "L": "Landed",
            "D": "Diverted",
            "C": "Cancelled",
            "NO": "Not Operational",
            "DN": "Data Needed"
        },

        // this function parses the initial query and sends out additional queries
        // as necessary for cities with multiple airports
        route: function(api_result) {
            "use strict";

            // prevent jQuery from appending "_={timestamp}" in our url when we use $.getScript
            $.ajaxSetup({ cache: true });

            // Get the original query to continue polling for other potential airports
            // and for filtering results by airline
            var script = $('[src*="/js/spice/flights/route/"]')[0],
                source = $(script).attr("src"),
                match  = source.match(/\/js\/spice\/flights\/route\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)/),
                queriedSrcAirports = match[2].split('%2C'),
                queriedDstAirports = match[3].split('%2C');

            this.queriedAirlines = match[1].split('%2C');
            this.sourceCity = match[10].replace('%2B', "+");
            this.destinationCity = match[11].replace('%2B', "+");

            // create all remaining source/destination pairs that have not yet been polled for
            for (var srcCounter = 0; srcCounter < queriedSrcAirports.length; srcCounter++) {

                for (var dstCounter = 0; dstCounter < queriedDstAirports.length; dstCounter++) {

                    // skip the first pair because the initial spice-to already
                    // obtained this result
                    if (srcCounter === 0 && dstCounter === 0)
                        continue;

                    $.getScript(this.path + "/route_helper/"
                                + queriedSrcAirports[srcCounter] + "/"
                                + queriedDstAirports[dstCounter] + "/arr/"
                                + match[6] + "/" + match[7] + "/" + match[8] +
                                "/" + match[9]);
                }
            }

            // Check if we have anything returned.
            if (!api_result || !api_result.flightStatuses) {
                return Spice.failed('route');
            }

            this.display(api_result);
        },

        // this helper function allows us to query for multiple airports with the
        // same city name; for example, New York maps to JFK and LGA
        route_helper: function(api_result) {
            "use strict";

            // Check if we have anything returned.
            if (!api_result || !api_result.flightStatuses) {
                return;
            }

            this.display(api_result);
        },

        // this function displays flight results; much of this code is copied from the
        // "airlines" spice
        display: function(api_result) {

            // Check if we have anything returned.
            if (!api_result || !api_result.flightStatuses || !api_result.appendix.airlines) {
                return;
            }

            // Create dictionaries to convert FlightStat codes to ICAO codes/airline names
            var dictFlightStats = {};
            $.each(api_result.appendix.airlines, function(index, value) {
                dictFlightStats[value.fs] = {
                    "icao": value.icao,
                    "name": value.name,
                };
            });

            // Create dictionaries to convert FlightStat codes to ICAO codes/airline names
            var dictAirportStats = {};
            $.each(api_result.appendix.airports, function(index, value) {
                dictAirportStats[value.fs] = value;
            });

            // Check if flight is an array or not.
            var flight = [];
            if (!($.isArray(api_result.flightStatuses))) {
                flight = [api_result.flightStatuses];
            } else {
                flight = api_result.flightStatuses;
            }

            // array of flights
            var results = [];

            // package up the flights into the result array
            for (var i = 0; i < flight.length; i++) {

                // compile all airline and codeshare codes for each returned flight
                var carrierCodes = [{"fsCode": flight[i].carrierFsCode, "flightNumber": flight[i].flightNumber}];

                if (flight[i].codeshares) {

                    $.each(flight[i].codeshares, function(codeShareIndex, flightCodeShare) {
                        carrierCodes.push(flightCodeShare);
                    });

                }

                // this loop iterates through all codeshared codes for the current flight result
                // once we find a matching carrier code, we break out of this loop
                for (var carriersIndex = 0; carriersIndex < carrierCodes.length; carriersIndex++) {

                    if (this.queriedAirlines.indexOf(dictFlightStats[carrierCodes[carriersIndex].fsCode].icao) !== -1) {

                        var departureDate =
                            (flight[i].operationalTimes.actualGateDeparture
                                && flight[i].operationalTimes.actualGateDeparture.dateLocal)
                            || (flight[i].operationalTimes.estimatedGateDeparture
                                && flight[i].operationalTimes.estimatedGateDeparture.dateLocal)
                            || (flight[i].operationalTimes.scheduledGateDeparture
                                && flight[i].operationalTimes.scheduledGateDeparture.dateLocal)
                            || flight[i].operationalTimes.flightPlanPlannedDeparture.dateLocal;

                        departureDate = DDG.getDateFromString(departureDate.toString());

                        var arrivalDate =
                            (flight[i].operationalTimes.actualGateArrival
                                && flight[i].operationalTimes.actualGateArrival.dateLocal)
                            || (flight[i].operationalTimes.estimatedGateArrival
                                && flight[i].operationalTimes.estimatedGateArrival.dateLocal)
                            || (flight[i].operationalTimes.scheduledGateArrival
                                && flight[i].operationalTimes.scheduledGateArrival.dateLocal)
                            || flight[i].operationalTimes.flightPlanPlannedArrival.dateLocal;

                        arrivalDate = DDG.getDateFromString(arrivalDate.toString());

                        var scheduledDepartureDate =
                            (flight[i].operationalTimes.scheduledGateDeparture
                                && flight[i].operationalTimes.scheduledGateDeparture.dateLocal)
                            || flight[i].operationalTimes.flightPlanPlannedDeparture.dateLocal;

                        scheduledDepartureDate = DDG.getDateFromString(scheduledDepartureDate.toString());

                        var scheduledArrivalDate =
                        (flight[i].operationalTimes.scheduledGateArrival
                            && flight[i].operationalTimes.scheduledGateArrival.dateLocal)
                        || flight[i].operationalTimes.flightPlanPlannedArrival.dateLocal;

                        scheduledArrivalDate = DDG.getDateFromString(scheduledArrivalDate.toString());

                        // Get the weekday and the day.
                        var dateObject = new Date(departureDate);
                        var date = dateObject.toDateString();
                        date = date.split(" ");

                        function not_empty(value) {
                            return value !== undefined && value !== '';
                        }

                        var departing_airport = dictAirportStats[flight[i].departureAirportFsCode];
                        var departing_location = [
                            departing_airport.city,
                            departing_airport.stateCode,
                            departing_airport.countryCode
                        ].filter(not_empty).join(', ');

                        var arriving_airport = dictAirportStats[flight[i].arrivalAirportFsCode];
                        var arriving_location = [
                            arriving_airport.city,
                            arriving_airport.stateCode,
                            arriving_airport.countryCode
                        ].filter(not_empty).join(', ');

                        var departing = {
                                airportTimezone: "0",
                                airport: departing_airport,
                                location: departing_location,
                                terminal: (flight[i].airportResources && flight[i].airportResources.departureTerminal) || "N/A",
                                gate: (flight[i].airportResources && flight[i].airportResources.departureGate) || "N/A",
                                isDeparted: true,
                                departureDateF: date[0] + ", " + date[1] + " " + date[2],
                            },

                            arriving = {
                                airportTimezone: "0",
                                airport: arriving_airport,
                                location: arriving_location,
                                terminal: (flight[i].airportResources && flight[i].airportResources.arrivalTerminal) || "N/A",
                                gate: (flight[i].airportResources && flight[i].airportResources.arrivalGate) || "N/A",
                                isDeparted: false
                            };

                        var is_on_time = this.onTime(flight[i], departureDate, arrivalDate, scheduledDepartureDate, scheduledArrivalDate);
                        if (is_on_time.length != 2) {
                            return Spice.failed('route');
                        }

                        var status = is_on_time[0];

                        results.push({
                            flight: flight[i],
                            airlineName: dictFlightStats[carrierCodes[carriersIndex].fsCode].name,
                            airlineCode: carrierCodes[carriersIndex].fsCode,
                            flightNumber: carrierCodes[carriersIndex].flightNumber,
                            departing: departing,
                            arriving: arriving,
                            departureDate: departureDate,
                            arrivalDate: arrivalDate,
                            scheduledDepartureDate: scheduledDepartureDate,
                            scheduledArrivalDate: scheduledArrivalDate,
                            status: status,
                            is_on_time: is_on_time[1] ? 'ok' : 'not',
                        });
                        break;
                    }
                }
            }

            if (results.length === 0) {
                return Spice.failed('route');
            }

            DDG.require('moment.js', function() {
                Spice.add({
                    data: results,
                    id: "route",
                    name: "Route",
                    meta: {
                        minItemsForModeSwitch: 3,
                        sourceName: 'FlightStats',
                        sourceUrl: "http://www.flightstats.com/go/FlightStatus/flightStatusByRoute.do?"
                            + "departure=" + this.sourceCity
                            + "&arrival=" + this.destinationCity,
                        itemType: 'flights'
                    },
                    normalize: function(item) {
                        var status_text,
                            display_datetime;

                        if (!item.is_on_time) {
                            status_text = 'Scheduled';
                            display_datetime = moment(item.scheduledArrivalDate);
                        } else {
                            if (moment(item.arrivalDate).isBefore(moment())) {
                                status_text = 'Arrived';
                                display_datetime = moment(item.arrivalDate);
                            } else {
                                if (moment(item.scheduledDepartureDate).isAfter(moment())) {
                                    status_text = 'Departs';
                                    display_datetime = moment(item.scheduledDepartureDate);
                                } else {
                                    status_text = 'Arrives';
                                    display_datetime = moment(item.scheduledArrivalDate);
                                }
                            }
                        }

                        var scheduled_arrival = moment(item.scheduledArrivalDate),
                            scheduled_depart = moment(item.scheduledDepartureDate);

                        var same_date = (scheduled_arrival.date() === scheduled_depart.date());

                        var progress_percent = 100;
                        var time_total = item.scheduledArrivalDate.getTime() - item.scheduledDepartureDate.getTime();
                        var time_remaining = item.scheduledArrivalDate.getTime() - (new Date()).getTime();
                        if (status_text !== 'Arrived') {
                            progress_percent = 100 * (time_total - time_remaining) / time_total;
                            if (progress_percent < 0) progress_percent = 0;
                        }

                        return {
                            url: "http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?"
                                + "airlineCode=" + item.airlineCode
                                + "&flightNumber=" + item.flightNumber
                                + "&departureDate="
                                + item.departureDate.getFullYear() + "-"
                                + (item.departureDate.getMonth() + 1) + "-"
                                + item.departureDate.getDate(),
                            datetime: display_datetime.fromNow(),
                            progress_percent: progress_percent,
                            status_text: status_text,
                            scheduled_arrival: same_date ? scheduled_arrival.format('LT') : scheduled_arrival.format('LT (MMM DD)'),
                            scheduled_depart: same_date ? scheduled_depart.format('LT') : scheduled_depart.format('LT (MMM DD)'),
                            has_landed: (item.status == 'Landed'),
                            has_arrived: status_text === 'Arrived'
                        }
                    },
                    sort_fields: {
                        departureDate: function(a, b) {
                            a = +new Date(a.departureDate);
                            b = +new Date(b.departureDate);
                            return ((a < b) ? -1 : (a > b ? 1 : 0));
                        }
                    },
                    sort_default: 'departureDate',
                    templates: {
                        group: 'base',
                        detail: false,
                        options: {
                            content: Spice.flights_route.content
                        },
                        variants: {
                            tile: 'xwide'
                        }
                    },
                    onShow: function(item) {
                        $('.tile__landed').parents('.tile__body').addClass('has_landed');
                    }
                });
            });
        },

        // Check if the airplane is on-time or delayed.
        onTime: function onTime(flight, departureDate, arrivalDate, scheduledDeparture, scheduledArrival) {

            var deltaDepart = new Date(departureDate) - scheduledDeparture,
                deltaArrive = new Date(arrivalDate) - scheduledArrival;

            if (flight.status === "A" || flight.status === "S") {
                if (this.MILLIS_PER_MIN * 5 < deltaDepart && this.MILLIS_PER_MIN * 5 < deltaArrive) {
                    return ["Delayed", false];
                } else {
                    return ["On Time", true];
                }
            }
            return [this.STATUS[flight.status], true];
        }
    }

    //--- make the appropriate DDG spice functions globally available

    // this is the primary function for user flight queries by route
    ddg_spice_flights_route = ddg_spice_flights.route.bind(ddg_spice_flights);

    // this helper function queries individual source and destination airport pairs
    ddg_spice_flights_route_helper = ddg_spice_flights.route_helper.bind(ddg_spice_flights);

}(this))
<commit_msg>provided for when scheduled arrival has past, but landing not confirmed<commit_after>(function(env) {

    var ddg_spice_flights = {

        path: "/js/spice/flights",
        id: 'route',

        // store the user's airline and city search information
        queriedAirlines: null,
        sourceCity: null,
        destinationCity: null,

        // define some static variables for callback and helpers
        MILLIS_PER_MIN: 60000,
        MILLIS_PER_HOUR: this.MILLIS_PER_MIN * 60,
        STATUS: {
            "S": "Scheduled",
            "A": "In the air",
            "U": "Unknown status",
            "R": "Redirected flight",
            "L": "Landed",
            "D": "Diverted",
            "C": "Cancelled",
            "NO": "Not Operational",
            "DN": "Data Needed"
        },

        // this function parses the initial query and sends out additional queries
        // as necessary for cities with multiple airports
        route: function(api_result) {
            "use strict";

            // prevent jQuery from appending "_={timestamp}" in our url when we use $.getScript
            $.ajaxSetup({ cache: true });

            // Get the original query to continue polling for other potential airports
            // and for filtering results by airline
            var script = $('[src*="/js/spice/flights/route/"]')[0],
                source = $(script).attr("src"),
                match  = source.match(/\/js\/spice\/flights\/route\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)\/(.*)/),
                queriedSrcAirports = match[2].split('%2C'),
                queriedDstAirports = match[3].split('%2C');

            this.queriedAirlines = match[1].split('%2C');
            this.sourceCity = match[10].replace('%2B', "+");
            this.destinationCity = match[11].replace('%2B', "+");

            // create all remaining source/destination pairs that have not yet been polled for
            for (var srcCounter = 0; srcCounter < queriedSrcAirports.length; srcCounter++) {

                for (var dstCounter = 0; dstCounter < queriedDstAirports.length; dstCounter++) {

                    // skip the first pair because the initial spice-to already
                    // obtained this result
                    if (srcCounter === 0 && dstCounter === 0)
                        continue;

                    $.getScript(this.path + "/route_helper/"
                                + queriedSrcAirports[srcCounter] + "/"
                                + queriedDstAirports[dstCounter] + "/arr/"
                                + match[6] + "/" + match[7] + "/" + match[8] +
                                "/" + match[9]);
                }
            }

            // Check if we have anything returned.
            if (!api_result || !api_result.flightStatuses) {
                return Spice.failed('route');
            }

            this.display(api_result);
        },

        // this helper function allows us to query for multiple airports with the
        // same city name; for example, New York maps to JFK and LGA
        route_helper: function(api_result) {
            "use strict";

            // Check if we have anything returned.
            if (!api_result || !api_result.flightStatuses) {
                return;
            }

            this.display(api_result);
        },

        // this function displays flight results; much of this code is copied from the
        // "airlines" spice
        display: function(api_result) {

            // Check if we have anything returned.
            if (!api_result || !api_result.flightStatuses || !api_result.appendix.airlines) {
                return;
            }

            // Create dictionaries to convert FlightStat codes to ICAO codes/airline names
            var dictFlightStats = {};
            $.each(api_result.appendix.airlines, function(index, value) {
                dictFlightStats[value.fs] = {
                    "icao": value.icao,
                    "name": value.name,
                };
            });

            // Create dictionaries to convert FlightStat codes to ICAO codes/airline names
            var dictAirportStats = {};
            $.each(api_result.appendix.airports, function(index, value) {
                dictAirportStats[value.fs] = value;
            });

            // Check if flight is an array or not.
            var flight = [];
            if (!($.isArray(api_result.flightStatuses))) {
                flight = [api_result.flightStatuses];
            } else {
                flight = api_result.flightStatuses;
            }

            // array of flights
            var results = [];

            // package up the flights into the result array
            for (var i = 0; i < flight.length; i++) {

                // compile all airline and codeshare codes for each returned flight
                var carrierCodes = [{"fsCode": flight[i].carrierFsCode, "flightNumber": flight[i].flightNumber}];

                if (flight[i].codeshares) {

                    $.each(flight[i].codeshares, function(codeShareIndex, flightCodeShare) {
                        carrierCodes.push(flightCodeShare);
                    });

                }

                // this loop iterates through all codeshared codes for the current flight result
                // once we find a matching carrier code, we break out of this loop
                for (var carriersIndex = 0; carriersIndex < carrierCodes.length; carriersIndex++) {

                    if (this.queriedAirlines.indexOf(dictFlightStats[carrierCodes[carriersIndex].fsCode].icao) !== -1) {

                        var departureDate =
                            (flight[i].operationalTimes.actualGateDeparture
                                && flight[i].operationalTimes.actualGateDeparture.dateLocal)
                            || (flight[i].operationalTimes.estimatedGateDeparture
                                && flight[i].operationalTimes.estimatedGateDeparture.dateLocal)
                            || (flight[i].operationalTimes.scheduledGateDeparture
                                && flight[i].operationalTimes.scheduledGateDeparture.dateLocal)
                            || flight[i].operationalTimes.flightPlanPlannedDeparture.dateLocal;

                        departureDate = DDG.getDateFromString(departureDate.toString());

                        var arrivalDate =
                            (flight[i].operationalTimes.actualGateArrival
                                && flight[i].operationalTimes.actualGateArrival.dateLocal)
                            || (flight[i].operationalTimes.estimatedGateArrival
                                && flight[i].operationalTimes.estimatedGateArrival.dateLocal)
                            || (flight[i].operationalTimes.scheduledGateArrival
                                && flight[i].operationalTimes.scheduledGateArrival.dateLocal)
                            || flight[i].operationalTimes.flightPlanPlannedArrival.dateLocal;

                        arrivalDate = DDG.getDateFromString(arrivalDate.toString());

                        var scheduledDepartureDate =
                            (flight[i].operationalTimes.scheduledGateDeparture
                                && flight[i].operationalTimes.scheduledGateDeparture.dateLocal)
                            || flight[i].operationalTimes.flightPlanPlannedDeparture.dateLocal;

                        scheduledDepartureDate = DDG.getDateFromString(scheduledDepartureDate.toString());

                        var scheduledArrivalDate =
                        (flight[i].operationalTimes.scheduledGateArrival
                            && flight[i].operationalTimes.scheduledGateArrival.dateLocal)
                        || flight[i].operationalTimes.flightPlanPlannedArrival.dateLocal;

                        scheduledArrivalDate = DDG.getDateFromString(scheduledArrivalDate.toString());

                        // Get the weekday and the day.
                        var dateObject = new Date(departureDate);
                        var date = dateObject.toDateString();
                        date = date.split(" ");

                        function not_empty(value) {
                            return value !== undefined && value !== '';
                        }

                        var departing_airport = dictAirportStats[flight[i].departureAirportFsCode];
                        var departing_location = [
                            departing_airport.city,
                            departing_airport.stateCode,
                            departing_airport.countryCode
                        ].filter(not_empty).join(', ');

                        var arriving_airport = dictAirportStats[flight[i].arrivalAirportFsCode];
                        var arriving_location = [
                            arriving_airport.city,
                            arriving_airport.stateCode,
                            arriving_airport.countryCode
                        ].filter(not_empty).join(', ');

                        var departing = {
                                airportTimezone: "0",
                                airport: departing_airport,
                                location: departing_location,
                                terminal: (flight[i].airportResources && flight[i].airportResources.departureTerminal) || "N/A",
                                gate: (flight[i].airportResources && flight[i].airportResources.departureGate) || "N/A",
                                isDeparted: true,
                                departureDateF: date[0] + ", " + date[1] + " " + date[2],
                            },

                            arriving = {
                                airportTimezone: "0",
                                airport: arriving_airport,
                                location: arriving_location,
                                terminal: (flight[i].airportResources && flight[i].airportResources.arrivalTerminal) || "N/A",
                                gate: (flight[i].airportResources && flight[i].airportResources.arrivalGate) || "N/A",
                                isDeparted: false
                            };

                        var is_on_time = this.onTime(flight[i], departureDate, arrivalDate, scheduledDepartureDate, scheduledArrivalDate);
                        if (is_on_time.length != 2) {
                            return Spice.failed('route');
                        }

                        var status = is_on_time[0];

                        results.push({
                            flight: flight[i],
                            airlineName: dictFlightStats[carrierCodes[carriersIndex].fsCode].name,
                            airlineCode: carrierCodes[carriersIndex].fsCode,
                            flightNumber: carrierCodes[carriersIndex].flightNumber,
                            departing: departing,
                            arriving: arriving,
                            departureDate: departureDate,
                            arrivalDate: arrivalDate,
                            scheduledDepartureDate: scheduledDepartureDate,
                            scheduledArrivalDate: scheduledArrivalDate,
                            status: status,
                            is_on_time: is_on_time[1] ? 'ok' : 'not',
                        });
                        break;
                    }
                }
            }

            if (results.length === 0) {
                return Spice.failed('route');
            }

            DDG.require('moment.js', function() {
                Spice.add({
                    data: results,
                    id: "route",
                    name: "Route",
                    meta: {
                        minItemsForModeSwitch: 3,
                        sourceName: 'FlightStats',
                        sourceUrl: "http://www.flightstats.com/go/FlightStatus/flightStatusByRoute.do?"
                            + "departure=" + this.sourceCity
                            + "&arrival=" + this.destinationCity,
                        itemType: 'flights'
                    },
                    normalize: function(item) {
                        var status_text,
                            display_datetime;

                        if (!item.is_on_time) {
                            status_text = 'Scheduled';
                            display_datetime = moment(item.scheduledArrivalDate);
                        } else {
                            if (moment(item.arrivalDate).isBefore(moment())) {
                                status_text = 'Arrived';
                                display_datetime = moment(item.arrivalDate);
                            } else {
                                if (moment(item.scheduledDepartureDate).isAfter(moment())) {
                                    status_text = 'Departs';
                                    display_datetime = moment(item.scheduledDepartureDate);
                                } else {
                                    if (moment(item.scheduledArrivalDate).isBefore(moment())) {
                                        status_text = 'Scheduled arrival';
                                    } else {
                                        status_text = 'Arrives';
                                    }
                                    display_datetime = moment(item.scheduledArrivalDate);
                                }
                            }
                        }

                        var scheduled_arrival = moment(item.scheduledArrivalDate),
                            scheduled_depart = moment(item.scheduledDepartureDate);

                        var same_date = (scheduled_arrival.date() === scheduled_depart.date());

                        var progress_percent = 100;
                        var time_total = item.scheduledArrivalDate.getTime() - item.scheduledDepartureDate.getTime();
                        var time_remaining = item.scheduledArrivalDate.getTime() - (new Date()).getTime();
                        if (status_text !== 'Arrived') {
                            progress_percent = 100 * (time_total - time_remaining) / time_total;
                            if (progress_percent < 0) progress_percent = 0;
                            if (progress_percent > 100) progress_percent = 100;
                        }

                        return {
                            url: "http://www.flightstats.com/go/FlightStatus/flightStatusByFlight.do?"
                                + "airlineCode=" + item.airlineCode
                                + "&flightNumber=" + item.flightNumber
                                + "&departureDate="
                                + item.departureDate.getFullYear() + "-"
                                + (item.departureDate.getMonth() + 1) + "-"
                                + item.departureDate.getDate(),
                            datetime: display_datetime.fromNow(),
                            progress_percent: progress_percent,
                            status_text: status_text,
                            scheduled_arrival: same_date ? scheduled_arrival.format('LT') : scheduled_arrival.format('LT (MMM DD)'),
                            scheduled_depart: same_date ? scheduled_depart.format('LT') : scheduled_depart.format('LT (MMM DD)'),
                            has_landed: (item.status == 'Landed'),
                            has_arrived: status_text === 'Arrived'
                        }
                    },
                    sort_fields: {
                        departureDate: function(a, b) {
                            a = +new Date(a.departureDate);
                            b = +new Date(b.departureDate);
                            return ((a < b) ? -1 : (a > b ? 1 : 0));
                        }
                    },
                    sort_default: 'departureDate',
                    templates: {
                        group: 'base',
                        detail: false,
                        options: {
                            content: Spice.flights_route.content
                        },
                        variants: {
                            tile: 'xwide'
                        }
                    },
                    onShow: function(item) {
                        $('.tile__landed').parents('.tile__body').addClass('has_landed');
                    }
                });
            });
        },

        // Check if the airplane is on-time or delayed.
        onTime: function onTime(flight, departureDate, arrivalDate, scheduledDeparture, scheduledArrival) {

            var deltaDepart = new Date(departureDate) - scheduledDeparture,
                deltaArrive = new Date(arrivalDate) - scheduledArrival;

            if (flight.status === "A" || flight.status === "S") {
                if (this.MILLIS_PER_MIN * 5 < deltaDepart && this.MILLIS_PER_MIN * 5 < deltaArrive) {
                    return ["Delayed", false];
                } else {
                    return ["On Time", true];
                }
            }
            return [this.STATUS[flight.status], true];
        }
    }

    //--- make the appropriate DDG spice functions globally available

    // this is the primary function for user flight queries by route
    ddg_spice_flights_route = ddg_spice_flights.route.bind(ddg_spice_flights);

    // this helper function queries individual source and destination airport pairs
    ddg_spice_flights_route_helper = ddg_spice_flights.route_helper.bind(ddg_spice_flights);

}(this))
<|endoftext|>


<commit_before>/*!
  * depmanjs - copyright (c) Egor Sharapov 2013
  * https://github.com/egych/depmanjs
  * MIT license
  */
(function (window, document) {
  var DepMan,
      Manager,
      Vendor,
      CONFIG,
      head = document.getElementsByTagName('head')[0],
      start_time = +new Date(),
      log = function (msg) { // wrapper for console.log
        if ((CONFIG.production !== true) && console && (typeof (console.log) !== 'undefined')) {
          console.log('[' + (+new Date()-start_time)/1000 + ']  ' + msg);
        }
      };

  /**
    * Project config, can be changed with depman.config({}) function
    */
  CONFIG = {
    project: 'Project name',
    version: '0.0.1',
    production: true, // production env allow cache included files in browser by CONFIG.version param
    path: '/js/', // depmanjs file-structure root-path
    vendor: {}  // used non-depmanjs scripts
  };

  /**
    * Vendor scripts
    * @constructor
    * @this {Vendor}
    * @return {Vendor}
    */
  Vendor = function (manager) {
    this.manager = manager;
  };

  /**
    * Check namespace for vendor accessory
    * @param {String} ns Namespace
    * @return {Boolean}
    */
  Vendor.prototype.check = function (ns) {
    if (ns.indexOf('vendor.') === 0) {
      return true;
    }
    return false;
  };

  /**
    * Get vendor object in config if it isset
    * @param {String} ns Vendor module namespace
    * @return {Object|Boolean} If object by namespace isset, then return object, else return false
    */
  Vendor.prototype.getConfig = function (ns) {
    var parts = ns.split('.'),
        parent = CONFIG;

    for (var i = 0, l = parts.length; i < l; i += 1) {
      if (typeof parent[parts[i]] === 'undefined') {
        return false;
      }
      parent = parent[parts[i]];
    }

    return parent;
  };

  /**
    * Get vendor module
    * @param {String} ns Vendor module namespace
    * @return {Object|undefined} If module is not loaded, then return undefined
    */
  Vendor.prototype.get = function (ns) {
    var vendor = this.getConfig(ns);
    if (typeof vendor === 'string') {
      return window[vendor];
    } else {
      if (typeof vendor.attach === 'string') {
        return window[vendor.attach];
      } else {
        try {
          return this.attach((vendor.use || []), vendor.attach);
        } catch (e) {
          return undefined;
        }
      }
    }
    return undefined;
  };

  /**
    * If vendor script has custom path, return custom path
    * @param {String} ns Vendor module namespace
    * @return {String|Boolean} If module has custom path, then return path string, else return false
    */
  Vendor.prototype.customPath = function (ns) {
    var vendor = this.getConfig(ns);
    if (vendor !== false) {
      return vendor.path;
    }
    return false;
  };

  /**
    * If vendor has attach function, then trigger it with deps args
    * @param {Array} deps Vendor dependencies
    * @param {Function} attach Attach function
    * @return {Mixed} Attach function result
    */
  Vendor.prototype.attach = function (deps, attach) {
    var args = [];

    for (var i in deps) {
      args.push(this.get(deps[i]));
    }
    return attach.apply({}, args);
  };

  /**
    * Load vendor if it has dependencies
    * @param {String} ns Vendor namespace
    * @return {Boolean} If vendor has hard deps, then it can be synchronous loaded
    */
  Vendor.prototype.load = function (ns) {
    var vendor_config = this.getConfig(ns),
        self = this,
        callback = function () {
          if (vendor_config.sync === true) {
            self.manager.load(ns);
          }
        };

    if (vendor_config && (typeof vendor_config.use === 'object')) {
      this.manager.add(vendor_config.use, callback, ns);

      return (vendor_config.sync === true);
    }

    return false;
  };

  /**
    * Dependency manager
    * @constructor
    * @this {Manager}
    * @return {Manager}
    */
  Manager = function () {
    this.queue = [];
    this.is_being_load = [];

    this.modules = {};

    this.vendor = new Vendor(this);

    return this;
  };

  /**
    * Check if module is already loaded
    * @param {String} ns Namespace of module
    * @param {Object} val Value
    * @return {Boolean}
    */
  Manager.prototype.ns = function (ns, val) {
    var parts = ns.split('.'),
        parent = this.modules,
        hasVal = typeof val !== 'undefined';

    for (var i = 0, l = parts.length; i < l; i += 1) {
      if (typeof parent[parts[i]] === 'undefined') {
        if (hasVal) {
          if (i+1 === l) {
            parent[parts[i]] = val;
          } else {
            parent[parts[i]] = {};
          }
        } else {
          return false;
        }
      }
      parent = parent[parts[i]];
    }

    if (hasVal) {
      return parent;
    } else {
      return true;
    }
  };

  /**
    * Defining new namespace
    * @param {String} ns Namespace path
    * @param {Object} val Value, if need to set as it been defined
    * @return {Object}
    */
  Manager.prototype.namespace = function (ns, val) {
    return this.ns(ns, (val || {}));
  };

  /**
    * Check if module is already loaded
    * @param {String} ns Namespace of module
    * @return {Boolean}
    */
  Manager.prototype.isLoaded = function (ns) {
    if (this.vendor.check(ns)) {
      return (typeof this.vendor.get(ns) !== 'undefined');
    } else {
      return this.ns(ns);
    }
  };

  /**
    * Add module namespace to load-queue
    * @param {Array} requres Array of module dependencies
    * @param {Function} callback Callback function
    * @param {String} ns Namespace of module that being loaded
    * @param {String} version Module version
    * @return {Manager} Возвращает объект UseManager
    */
  Manager.prototype.add = function(requires, cb, ns, version) {
    var deps = [],
        vendor_use,
        self = this,
        vendor_wait = false;

    for (var i = 0, l = requires.length; i < l; i += 1) {
      // if it already loading then do nothing
      if (this.is_being_load.indexOf(requires[i]) >= 0) {
        continue;
      }

      if (this.vendor.check(requires[i]) && (typeof this.vendor.get(requires[i]) === 'undefined')) {
        vendor_wait = this.vendor.load(requires[i], this);
      }
      if (!vendor_wait) {
        this.load(requires[i], version);
      }
      deps.push(requires[i]);
    }

    this.queue.push({
      deps: deps,
      callback: cb,
      ns: ns,
      loaded: []
    });

    this.checkQueue(ns);

    return this;
  };

  /**
    * Check array or object length
    * @param {Object} obj Object or array
    * @return {Number} Количество элементов в массиве
    */
  Manager.prototype.objLength = function(obj) {
    var i, count = 0;

    for (i in obj) {
      if (typeof obj[i] !== 'undefined' && obj.hasOwnProperty(i)) {
        count += 1;
      }
    }

    return count;
  };

  /**
    * Converts namespace to script filename
    * @param {String} ns Namespace string
    * @return {String} Filename
    */
  Manager.prototype.ns2File = function (ns) {
    var vendor_path = this.vendor.customPath(ns);
    if (typeof vendor_path !== 'string') {
      return CONFIG.path + ns.split('.').join('/').toLowerCase() + '.js';
    }
    return vendor_path;
  };

  /**
    * Mix version of module and config version
    * @param {String} version Module version
    * @return {String} Mixed version of module and config versions
    */
  Manager.prototype.mixVersion = function (version) {
    var config_version = CONFIG.version.split('.'),
        module_version = [];

    version = (version || '0.0.0').split('.');
    for (var i = 0, l = config_version.length; i < l; i += 1) {
      module_version[i] = (config_version[i]|0)+(version[i]|0);
    }

    return module_version.join('.');
  };

  /**
    * Prepare namespace for load js-file
    * @param {String} ns Namespace of module, converts to filename with ns2File-function
    * @param {String} version Module version
    * @return {Manager}
    */
  Manager.prototype.load = function(ns, version) {
    if ((this.is_being_load.indexOf(ns) >= 0) || this.isLoaded(ns)) {
      this.checkQueue(ns);
      return;
    }

    var cacheParam = '?' + (CONFIG.production ? ('v'+this.mixVersion(version)) : (+new Date())),
        filename = this.ns2File(ns) + cacheParam;

    this.loadFile(filename, ns);
    this.is_being_load.push(ns);

    return this;
  };

  /**
    * Load js-file
    * @param {String} filename JS-filename
    * @param {String} ns Namespace of module to load
    */
  Manager.prototype.loadFile = function (filename, ns) {
    var script = document.createElement('script'),
        self = this;

    // IE
    script.onreadystatechange = function () {
      if (script.readyState === 'loaded' || script.readyState === 'complete') {
        script.onreadystatechange = null;
        log(ns.toString() + ' is loaded');
        self.checkQueue(ns);
      }
    };

    // other
    script.onload = function () {
      log(ns.toString() + ' is loaded');
      self.checkQueue(ns);
    };

    script.src = filename;
    head.appendChild(script);
  };

  /**
    * Get module if it loaded
    * @param {String} ns Namespace
    * @return {Mixed|Boolean} If module is loaded, then return module value, else return false
    */
  Manager.prototype.get = function (ns) {
    if (this.isLoaded(ns)) {
      if (this.vendor.check(ns)) {
        return this.vendor.get(ns);
      } else {
        return this.namespace(ns);
      }
    }
    return false;
  };

  /**
    * Check queue for loaded modules
    * @param {String} ns Namespace
    */
  Manager.prototype.checkQueue = function(ns) {
    var i, item, loaded_module;

    if (!ns) {
      return;
    }

    for (i in this.queue) {
      if (!this.queue.hasOwnProperty(i)) {
        continue;
      }

      item = this.queue[i];

      /**
        * Check loaded modules for initialize
        */
      for (var k = 0, l = item.deps.length; k < l; k++) {
        loaded_module = this.get(item.deps[k]);
        if (loaded_module !== false) {
          item.loaded[k] = loaded_module;
        }
      }

      /**
        * If loaded modules equal to required modules, then trigger callback-function and initialize module
        */
      if (this.objLength(item.deps) === this.objLength(item.loaded)) {
        this.namespace(item.ns, item.callback.apply({}, item.loaded));
        this.queue.splice(i, 1);
        this.checkQueue(item.ns);
        break;
      }
    }
  };

  /**
    * Base object, contains common library functions
    * @constructor
    * @this {DepMan}
    * @return {DepMan}
    */
  DepMan = function () {
    this.manager = new Manager();
    this.module_version = '0.0.0';
  };

  /**
    * Confugure your project
    * @param {Object} params Input params for configurating project
    */
  DepMan.prototype.config = function (params) {
    if (CONFIG.locked === true) {
      return false;
    }

    var config = CONFIG, key;
    params = params || {};

    for (key in config) {
      if (typeof params[key] !== 'undefined') {
        config[key] = params[key];
      }
    }
    this.version = config.version;

    CONFIG = config;
    CONFIG.locked = true;
    return true;
  };

  /**
    * Permit dependencies of module and perform a callback
    * @param {Array} requires Modules, that required for this module
    * @param {Function} callback Callback-function
    * @param {String} namespace Namespace of this module
    * @return {Boolean} true
    */
  DepMan.prototype.use = function (requires, callback, namespace) {
    var version = this.module_version;
    this.module_version = '0.0.0';
    namespace = namespace || 'auto_ns.'+(+new Date());
    callback = typeof callback === 'function' ? callback : (function () {});
    this.manager.add(requires, callback, namespace, version);

    return true;
  };

  /**
    * Adding vendor to project without adding this to project config
    * @param {Object} vendor Params like each vendor in config
    * @return {DepMan}
    */
  DepMan.prototype.addVendor = function (name, vendor) {
    if (typeof (CONFIG.vendor[name]) !== 'undefined') {
      log('This vendor already set in config: ' + name.toString());
    } else {
      CONFIG.vendor[name] = vendor;
    }
    return this;
  };

  /**
    * Set custom version of module being loaded
    * @param {String} version Version of module, for clear cache after module update
    * @return {DepMan}
    */
  DepMan.prototype.v = function (version) {
    if (typeof version === 'string') {
      this.module_version = version;
    }

    return this;
  };

  /**
   * Simple hash from string
   * @param {String} s Input string
   * @return {String} Hash
   */
	DepMan.prototype.getHash = function(s){
		return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
	};

  /**
   * Add css file to head
   * @param {String|Array} css CSS files or file need to add
   * @return {DepMan}
   */
	DepMan.prototype.addCSS = function (css) {
    var self = this, i,
        add_fn = function (url) {
      		url += (url.indexOf('?') >= 0 ? '&' : '?') + 'v=' + self.module_version;
      		var link = document.createElement('LINK'),
      		    hash = self.getHash(url);

      		if (!document.getElementById('css_'+hash)) {
      			link.href = url;
      			link.type = 'text/css';
      			link.rel = 'stylesheet';
      			link.id = 'css_' + hash;
      			document.getElementsByTagName('head')[0].appendChild(link);
      		}
        };

    css = (typeof css === 'string') ? [css] : css;

    for (i in css) {
      add_fn(css[i]);
    }

    return this;
	};

  window.depman = new DepMan();
} (this, document));<commit_msg>converted tabs to spaces<commit_after>/*!
  * depmanjs - copyright (c) Egor Sharapov 2013
  * https://github.com/egych/depmanjs
  * MIT license
  */
(function (window, document) {
  var DepMan,
      Manager,
      Vendor,
      CONFIG,
      head = document.getElementsByTagName('head')[0],
      start_time = +new Date(),
      log = function (msg) { // wrapper for console.log
        if ((CONFIG.production !== true) && console && (typeof (console.log) !== 'undefined')) {
          console.log('[' + (+new Date()-start_time)/1000 + ']  ' + msg);
        }
      };

  /**
    * Project config, can be changed with depman.config({}) function
    */
  CONFIG = {
    project: 'Project name',
    version: '0.0.1',
    production: true, // production env allow cache included files in browser by CONFIG.version param
    path: '/js/', // depmanjs file-structure root-path
    vendor: {}  // used non-depmanjs scripts
  };

  /**
    * Vendor scripts
    * @constructor
    * @this {Vendor}
    * @return {Vendor}
    */
  Vendor = function (manager) {
    this.manager = manager;
  };

  /**
    * Check namespace for vendor accessory
    * @param {String} ns Namespace
    * @return {Boolean}
    */
  Vendor.prototype.check = function (ns) {
    if (ns.indexOf('vendor.') === 0) {
      return true;
    }
    return false;
  };

  /**
    * Get vendor object in config if it isset
    * @param {String} ns Vendor module namespace
    * @return {Object|Boolean} If object by namespace isset, then return object, else return false
    */
  Vendor.prototype.getConfig = function (ns) {
    var parts = ns.split('.'),
        parent = CONFIG;

    for (var i = 0, l = parts.length; i < l; i += 1) {
      if (typeof parent[parts[i]] === 'undefined') {
        return false;
      }
      parent = parent[parts[i]];
    }

    return parent;
  };

  /**
    * Get vendor module
    * @param {String} ns Vendor module namespace
    * @return {Object|undefined} If module is not loaded, then return undefined
    */
  Vendor.prototype.get = function (ns) {
    var vendor = this.getConfig(ns);
    if (typeof vendor === 'string') {
      return window[vendor];
    } else {
      if (typeof vendor.attach === 'string') {
        return window[vendor.attach];
      } else {
        try {
          return this.attach((vendor.use || []), vendor.attach);
        } catch (e) {
          return undefined;
        }
      }
    }
    return undefined;
  };

  /**
    * If vendor script has custom path, return custom path
    * @param {String} ns Vendor module namespace
    * @return {String|Boolean} If module has custom path, then return path string, else return false
    */
  Vendor.prototype.customPath = function (ns) {
    var vendor = this.getConfig(ns);
    if (vendor !== false) {
      return vendor.path;
    }
    return false;
  };

  /**
    * If vendor has attach function, then trigger it with deps args
    * @param {Array} deps Vendor dependencies
    * @param {Function} attach Attach function
    * @return {Mixed} Attach function result
    */
  Vendor.prototype.attach = function (deps, attach) {
    var args = [];

    for (var i in deps) {
      args.push(this.get(deps[i]));
    }
    return attach.apply({}, args);
  };

  /**
    * Load vendor if it has dependencies
    * @param {String} ns Vendor namespace
    * @return {Boolean} If vendor has hard deps, then it can be synchronous loaded
    */
  Vendor.prototype.load = function (ns) {
    var vendor_config = this.getConfig(ns),
        self = this,
        callback = function () {
          if (vendor_config.sync === true) {
            self.manager.load(ns);
          }
        };

    if (vendor_config && (typeof vendor_config.use === 'object')) {
      this.manager.add(vendor_config.use, callback, ns);

      return (vendor_config.sync === true);
    }

    return false;
  };

  /**
    * Dependency manager
    * @constructor
    * @this {Manager}
    * @return {Manager}
    */
  Manager = function () {
    this.queue = [];
    this.is_being_load = [];

    this.modules = {};

    this.vendor = new Vendor(this);

    return this;
  };

  /**
    * Check if module is already loaded
    * @param {String} ns Namespace of module
    * @param {Object} val Value
    * @return {Boolean}
    */
  Manager.prototype.ns = function (ns, val) {
    var parts = ns.split('.'),
        parent = this.modules,
        hasVal = typeof val !== 'undefined';

    for (var i = 0, l = parts.length; i < l; i += 1) {
      if (typeof parent[parts[i]] === 'undefined') {
        if (hasVal) {
          if (i+1 === l) {
            parent[parts[i]] = val;
          } else {
            parent[parts[i]] = {};
          }
        } else {
          return false;
        }
      }
      parent = parent[parts[i]];
    }

    if (hasVal) {
      return parent;
    } else {
      return true;
    }
  };

  /**
    * Defining new namespace
    * @param {String} ns Namespace path
    * @param {Object} val Value, if need to set as it been defined
    * @return {Object}
    */
  Manager.prototype.namespace = function (ns, val) {
    return this.ns(ns, (val || {}));
  };

  /**
    * Check if module is already loaded
    * @param {String} ns Namespace of module
    * @return {Boolean}
    */
  Manager.prototype.isLoaded = function (ns) {
    if (this.vendor.check(ns)) {
      return (typeof this.vendor.get(ns) !== 'undefined');
    } else {
      return this.ns(ns);
    }
  };

  /**
    * Add module namespace to load-queue
    * @param {Array} requres Array of module dependencies
    * @param {Function} callback Callback function
    * @param {String} ns Namespace of module that being loaded
    * @param {String} version Module version
    * @return {Manager} Возвращает объект UseManager
    */
  Manager.prototype.add = function(requires, cb, ns, version) {
    var deps = [],
        vendor_use,
        self = this,
        vendor_wait = false;

    for (var i = 0, l = requires.length; i < l; i += 1) {
      // if it already loading then do nothing
      if (this.is_being_load.indexOf(requires[i]) >= 0) {
        continue;
      }

      if (this.vendor.check(requires[i]) && (typeof this.vendor.get(requires[i]) === 'undefined')) {
        vendor_wait = this.vendor.load(requires[i], this);
      }
      if (!vendor_wait) {
        this.load(requires[i], version);
      }
      deps.push(requires[i]);
    }

    this.queue.push({
      deps: deps,
      callback: cb,
      ns: ns,
      loaded: []
    });

    this.checkQueue(ns);

    return this;
  };

  /**
    * Check array or object length
    * @param {Object} obj Object or array
    * @return {Number} Количество элементов в массиве
    */
  Manager.prototype.objLength = function(obj) {
    var i, count = 0;

    for (i in obj) {
      if (typeof obj[i] !== 'undefined' && obj.hasOwnProperty(i)) {
        count += 1;
      }
    }

    return count;
  };

  /**
    * Converts namespace to script filename
    * @param {String} ns Namespace string
    * @return {String} Filename
    */
  Manager.prototype.ns2File = function (ns) {
    var vendor_path = this.vendor.customPath(ns);
    if (typeof vendor_path !== 'string') {
      return CONFIG.path + ns.split('.').join('/').toLowerCase() + '.js';
    }
    return vendor_path;
  };

  /**
    * Mix version of module and config version
    * @param {String} version Module version
    * @return {String} Mixed version of module and config versions
    */
  Manager.prototype.mixVersion = function (version) {
    var config_version = CONFIG.version.split('.'),
        module_version = [];

    version = (version || '0.0.0').split('.');
    for (var i = 0, l = config_version.length; i < l; i += 1) {
      module_version[i] = (config_version[i]|0)+(version[i]|0);
    }

    return module_version.join('.');
  };

  /**
    * Prepare namespace for load js-file
    * @param {String} ns Namespace of module, converts to filename with ns2File-function
    * @param {String} version Module version
    * @return {Manager}
    */
  Manager.prototype.load = function(ns, version) {
    if ((this.is_being_load.indexOf(ns) >= 0) || this.isLoaded(ns)) {
      this.checkQueue(ns);
      return;
    }

    var cacheParam = '?' + (CONFIG.production ? ('v'+this.mixVersion(version)) : (+new Date())),
        filename = this.ns2File(ns) + cacheParam;

    this.loadFile(filename, ns);
    this.is_being_load.push(ns);

    return this;
  };

  /**
    * Load js-file
    * @param {String} filename JS-filename
    * @param {String} ns Namespace of module to load
    */
  Manager.prototype.loadFile = function (filename, ns) {
    var script = document.createElement('script'),
        self = this;

    // IE
    script.onreadystatechange = function () {
      if (script.readyState === 'loaded' || script.readyState === 'complete') {
        script.onreadystatechange = null;
        log(ns.toString() + ' is loaded');
        self.checkQueue(ns);
      }
    };

    // other
    script.onload = function () {
      log(ns.toString() + ' is loaded');
      self.checkQueue(ns);
    };

    script.src = filename;
    head.appendChild(script);
  };

  /**
    * Get module if it loaded
    * @param {String} ns Namespace
    * @return {Mixed|Boolean} If module is loaded, then return module value, else return false
    */
  Manager.prototype.get = function (ns) {
    if (this.isLoaded(ns)) {
      if (this.vendor.check(ns)) {
        return this.vendor.get(ns);
      } else {
        return this.namespace(ns);
      }
    }
    return false;
  };

  /**
    * Check queue for loaded modules
    * @param {String} ns Namespace
    */
  Manager.prototype.checkQueue = function(ns) {
    var i, item, loaded_module;

    if (!ns) {
      return;
    }

    for (i in this.queue) {
      if (!this.queue.hasOwnProperty(i)) {
        continue;
      }

      item = this.queue[i];

      /**
        * Check loaded modules for initialize
        */
      for (var k = 0, l = item.deps.length; k < l; k++) {
        loaded_module = this.get(item.deps[k]);
        if (loaded_module !== false) {
          item.loaded[k] = loaded_module;
        }
      }

      /**
        * If loaded modules equal to required modules, then trigger callback-function and initialize module
        */
      if (this.objLength(item.deps) === this.objLength(item.loaded)) {
        this.namespace(item.ns, item.callback.apply({}, item.loaded));
        this.queue.splice(i, 1);
        this.checkQueue(item.ns);
        break;
      }
    }
  };

  /**
    * Base object, contains common library functions
    * @constructor
    * @this {DepMan}
    * @return {DepMan}
    */
  DepMan = function () {
    this.manager = new Manager();
    this.module_version = '0.0.0';
  };

  /**
    * Confugure your project
    * @param {Object} params Input params for configurating project
    */
  DepMan.prototype.config = function (params) {
    if (CONFIG.locked === true) {
      return false;
    }

    var config = CONFIG, key;
    params = params || {};

    for (key in config) {
      if (typeof params[key] !== 'undefined') {
        config[key] = params[key];
      }
    }
    this.version = config.version;

    CONFIG = config;
    CONFIG.locked = true;
    return true;
  };

  /**
    * Permit dependencies of module and perform a callback
    * @param {Array} requires Modules, that required for this module
    * @param {Function} callback Callback-function
    * @param {String} namespace Namespace of this module
    * @return {Boolean} true
    */
  DepMan.prototype.use = function (requires, callback, namespace) {
    var version = this.module_version;
    this.module_version = '0.0.0';
    namespace = namespace || 'auto_ns.'+(+new Date());
    callback = typeof callback === 'function' ? callback : (function () {});
    this.manager.add(requires, callback, namespace, version);

    return true;
  };

  /**
    * Adding vendor to project without adding this to project config
    * @param {Object} vendor Params like each vendor in config
    * @return {DepMan}
    */
  DepMan.prototype.addVendor = function (name, vendor) {
    if (typeof (CONFIG.vendor[name]) !== 'undefined') {
      log('This vendor already set in config: ' + name.toString());
    } else {
      CONFIG.vendor[name] = vendor;
    }
    return this;
  };

  /**
    * Set custom version of module being loaded
    * @param {String} version Version of module, for clear cache after module update
    * @return {DepMan}
    */
  DepMan.prototype.v = function (version) {
    if (typeof version === 'string') {
      this.module_version = version;
    }

    return this;
  };

  /**
   * Simple hash from string
   * @param {String} s Input string
   * @return {String} Hash
   */
  DepMan.prototype.getHash = function(s){
    return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
  };

  /**
   * Add css file to head
   * @param {String|Array} css CSS files or file need to add
   * @return {DepMan}
   */
  DepMan.prototype.addCSS = function (css) {
    var self = this, i,
        add_fn = function (url) {
          url += (url.indexOf('?') >= 0 ? '&' : '?') + 'v=' + self.module_version;
          var link = document.createElement('LINK'),
              hash = self.getHash(url);

          if (!document.getElementById('css_'+hash)) {
            link.href = url;
            link.type = 'text/css';
            link.rel = 'stylesheet';
            link.id = 'css_' + hash;
            document.getElementsByTagName('head')[0].appendChild(link);
          }
        };

    css = (typeof css === 'string') ? [css] : css;

    for (i in css) {
      add_fn(css[i]);
    }

    return this;
  };

  window.depman = new DepMan();
} (this, document));<|endoftext|>


<commit_before>function MontoProgramadoPip()
{
    var programado=new Array();

    event.preventDefault();

    $.ajax(
    {
        "url": base_url+"index.php/PrincipalPmi/MontoProgramado",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);
            //alert(respuesta);

            for(var i=0; i<registros.length; i++)
            {
                programado[i]=registros[i]["Cantidadpip"];

            }

           // $("#NumPip").text(sum); //OBTENER NUMERO DE PIP EN LA CABECERA
            $("#monto_programado").text("S/."+registros[0]["SumaCosto"]);
            $("#totalpip").text(registros[0]["NumProyectos"]);
            $("#monto_programado_nopip").text("S/."+registros[1]["SumaCosto"]);
            $("#totalnopip").text(registros[1]["NumProyectos"]);

        }
    });
}

function EstaProyProvincia()
{
    var provincias=new Array();

    event.preventDefault();

    $.ajax(
    {
        "url": base_url+"index.php/PrincipalPmi/EstadisticaPipProvinc",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);

            var sum=0;

            for(var i=0; i<registros.length; i++)
            {
                provincias[i]=registros[i]["Cantidadpip"];
                sum=provincias[i]+sum;
            }

            $("#NumPip").text(sum); //OBTENER NUMERO DE PIP EN LA CABECERA

            $("#NumPips").text(provincias);
            cantidadPIPAbancay=(100*(parseInt(provincias[0]))/sum);

            $("#CantidadPAbancay").text(provincias[0]); //LISTAR CANTIDAD DE PIP REPORTE GENERAL
            $("#porcentajeAban").text(cantidadPIPAbancay.toFixed(2)); //LISTAR PORCENTAJES EN EL GRAFICO PROYECTOS POR PRIVINCIAS EN TEXTO

            cantidadPIPAndahuaylas=(100*(parseInt(provincias[1]))/sum);

            $("#CantidadPAndahuaylas").text(provincias[1]);
            $("#porcentajeAnd").text(cantidadPIPAndahuaylas.toFixed(2));

            cantidadPIPAntabamba=(100*(parseInt(provincias[2]))/sum);

            $("#CantidadPAntabamba").text(provincias[2]);
            $("#porcentajeAnt").text(cantidadPIPAntabamba.toFixed(2));

            cantidadPIPAymaraes=(100*(parseInt(provincias[3]))/sum);

            $("#CantidadPAymaraes").text(provincias[3]);
            $("#porcentajeAy").text(cantidadPIPAymaraes.toFixed(2));

            cantidadPIPChincheros=(100*(parseInt(provincias[4]))/sum);

            $("#CantidadPChincheros").text(provincias[4]);
            $("#porcentajeChinc").text(cantidadPIPChincheros.toFixed(2));

            cantidadPIPCotabambas=(100*(parseInt(provincias[5]))/sum);

            $("#CantidadPCotabambas").text(provincias[5]);
            $("#porcentajeCotab").text(cantidadPIPCotabambas.toFixed(2));

            cantidadPIPGrau=(100*(parseInt(provincias[6]))/sum);

            $("#CantidadPGrau").text(provincias[6]);
            $("#porcentajeGrau").text(cantidadPIPGrau.toFixed(2));

            if ("undefined" != typeof Chart && (console.log("init_chart_doughnut"), $(".canvasDoughnut1").length))
            {
                var a=
                {
                    type: "doughnut",
                    tooltipFillColor: "rgba(51, 51, 51, 0.55)",
                    data:
                    {
                        labels: ["Abancay", "Andahuaylas", "Antabamba", "Aymaraes", "Contabambas", "Chincheros", "Grau"],
                        datasets: [
                        {
                            data: [cantidadPIPAbancay, cantidadPIPAndahuaylas, cantidadPIPAntabamba, cantidadPIPAymaraes, cantidadPIPChincheros, cantidadPIPCotabambas, cantidadPIPGrau],
                            backgroundColor: ["#3498DB", "#9B59B6", "#E74C3C", "#26B99A", "#B6CBD6", "#708B99", "#52C5E1"],
                            hoverBackgroundColor: ["#3498DB", "#B370CF", "#E95E4F", "#36CAAB", "#BDD3DF", "#7C96A3", "#52C5E1"]
                        }]
                    },
                    options: { legend: !1, responsive: !1 }
                };

                $(".canvasDoughnut1").each(function()
                {
                    var b=$(this);

                    new Chart(b, a)
                });
            }
        }
    });
}

var EstadistMontosPipProv=function()
{
    var MontosPipProv=new Array();

    var html1='';

    $.ajax(
    {
        "url": base_url+"index.php/PrincipalPmi/EstadisticaMontoPipProvincias",
        success: function(respuesta)
        {
            var registros=eval(respuesta);

            var suma=0;

            html1+='
'
				+'
'
					+'
Provincia
	'
					+'
Estadistica
	'
					+'
Montos
	'
				+'
'
			+'
'
			+'
';

            for(var i=0; i<registros.length; i++)
            {
                MontosPipProv[i]=registros[i]["MontoProyecto"]; //OPCIONAL, SIRVE PARA IMPRIR LOS MONTOS  EN DATOS PIP PROYECTOS POR PROVINCIA EN LOS DIV

                suma=MontosPipProv[i]+suma; //TOTAL MONTO PROYECTOS EN CABECERA

                html1+='
'
						+''+registros[i]['provincia']+'	'
						+'

	'
						+''+registros[i]['MontoProyecto']+'	'
				+'
';
            }

            html1+="
";

            $("#table-estaditMontPIPProv").html(html1);

            $("#MontoPipAbancay").html(MontosPipProv[0]); // MONTO TOTAL DE ABANCAY EN EL DIV MontoPipAbancay
            $("#MontoPipAndahuaylas").html(MontosPipProv[1]);
            $("#MontoPipAntabamba").html(MontosPipProv[2]);
            $("#MontoPipAymaraes").html(MontosPipProv[3]);
            $("#MontoPipChincheros").html(MontosPipProv[4]);
            $("#MontoPipCotabambas").html(MontosPipProv[5]);
            $("#MontoPipGrau").html(MontosPipProv[6]);
            $("#MontoTotalPip").html(suma); //OBTENER EL MONTO TOTAL DE PROYECTOS EN LA CABECERA
        }
    });
}

function EstadisticasPorCiclosInversion() {
    $.ajax({
        url: base_url+"index.php/PrincipalPmi/EstadisticaPipEstadoCiclo",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);
            var sql='';
            var NumProyectos=0;
            var total_proyectos=registros[0]["Num_Total"];
            var total_otros=registros[0]["TotalNoCiclo"];
            var panel_estadistica=$("#panel_estadistica_ciclo_inversion");
            var porcentaje=0.00;
            for (var i=0; i<registros.length; i++)
            {
                NumProyectos=registros[i]["Num_Proyectos"];
                porcentaje=Math.round((NumProyectos / total_proyectos) * 100);
                sql='
'
					+'
'
						+''+(registros[i]['nombre_estado_ciclo'].charAt(0).toUpperCase())+(registros[i]['nombre_estado_ciclo'].toLowerCase().substring(1))+''
					+'
'
					+'
'
						+'
'
							+'
'
								+porcentaje+'%'
							+'
'
						+'
'
					+'
'
					+'
'
						+''+NumProyectos+''
					+'
'
				+'
';

                panel_estadistica.append(sql);
            }

            porcentaje=Math.round((total_otros/total_proyectos)*100);

            sql='
'
				+'
'
					+'Otros'
				+'
'
				+'
'
					+'
'
						+'
'
						+porcentaje+'%'
						+'
'
					+'
'
				+'
'
				+'
'
					+''+total_otros+''
				+'
'
			+'
';

            panel_estadistica.append(sql);
        }
    });
}

function initMap()
{
    //var LatLng={lat: -25.363, lng: 131.044};
    var map=new google.maps.Map($('#map'),
    {
        zoom: 8,
        center: {lat: -14, lng: -73},
        //disableDefaultUI: true
    });

    $.ajax(
    {
        url: base_url+"index.php/PrincipalPmi/GetDatosUbicacion",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);

            var marker;

            for(var i=0; i<registros.length; i++)
            {
                marker=new google.maps.Marker(
                {
                    position: { lat : registros[i]["latitud"], lng: registros[i]["longitud"] },
                    map : map,
                    title : registros[i]["distrito"]+": "+registros[i]["nombre_pi"]
                });
            }
        }
    });
}

$(document).on('ready', function()
{
    EstaProyProvincia();
    MontoProgramadoPip();
    EstadistMontosPipProv();
    EstadisticasPorCiclosInversion();
});<commit_msg>Mapa DashBoard PMI<commit_after>function MontoProgramadoPip()
{
    var programado=new Array();

    event.preventDefault();

    $.ajax(
    {
        "url": base_url+"index.php/PrincipalPmi/MontoProgramado",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);
            //alert(respuesta);

            for(var i=0; i<registros.length; i++)
            {
                programado[i]=registros[i]["Cantidadpip"];

            }

           // $("#NumPip").text(sum); //OBTENER NUMERO DE PIP EN LA CABECERA
            $("#monto_programado").text("S/."+registros[0]["SumaCosto"]);
            $("#totalpip").text(registros[0]["NumProyectos"]);
            $("#monto_programado_nopip").text("S/."+registros[1]["SumaCosto"]);
            $("#totalnopip").text(registros[1]["NumProyectos"]);

        }
    });
}

function EstaProyProvincia()
{
    var provincias=new Array();

    event.preventDefault();

    $.ajax(
    {
        "url": base_url+"index.php/PrincipalPmi/EstadisticaPipProvinc",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);

            var sum=0;

            for(var i=0; i<registros.length; i++)
            {
                provincias[i]=registros[i]["Cantidadpip"];
                sum=provincias[i]+sum;
            }

            $("#NumPip").text(sum); //OBTENER NUMERO DE PIP EN LA CABECERA

            $("#NumPips").text(provincias);
            cantidadPIPAbancay=(100*(parseInt(provincias[0]))/sum);

            $("#CantidadPAbancay").text(provincias[0]); //LISTAR CANTIDAD DE PIP REPORTE GENERAL
            $("#porcentajeAban").text(cantidadPIPAbancay.toFixed(2)); //LISTAR PORCENTAJES EN EL GRAFICO PROYECTOS POR PRIVINCIAS EN TEXTO

            cantidadPIPAndahuaylas=(100*(parseInt(provincias[1]))/sum);

            $("#CantidadPAndahuaylas").text(provincias[1]);
            $("#porcentajeAnd").text(cantidadPIPAndahuaylas.toFixed(2));

            cantidadPIPAntabamba=(100*(parseInt(provincias[2]))/sum);

            $("#CantidadPAntabamba").text(provincias[2]);
            $("#porcentajeAnt").text(cantidadPIPAntabamba.toFixed(2));

            cantidadPIPAymaraes=(100*(parseInt(provincias[3]))/sum);

            $("#CantidadPAymaraes").text(provincias[3]);
            $("#porcentajeAy").text(cantidadPIPAymaraes.toFixed(2));

            cantidadPIPChincheros=(100*(parseInt(provincias[4]))/sum);

            $("#CantidadPChincheros").text(provincias[4]);
            $("#porcentajeChinc").text(cantidadPIPChincheros.toFixed(2));

            cantidadPIPCotabambas=(100*(parseInt(provincias[5]))/sum);

            $("#CantidadPCotabambas").text(provincias[5]);
            $("#porcentajeCotab").text(cantidadPIPCotabambas.toFixed(2));

            cantidadPIPGrau=(100*(parseInt(provincias[6]))/sum);

            $("#CantidadPGrau").text(provincias[6]);
            $("#porcentajeGrau").text(cantidadPIPGrau.toFixed(2));

            if ("undefined" != typeof Chart && (console.log("init_chart_doughnut"), $(".canvasDoughnut1").length))
            {
                var a=
                {
                    type: "doughnut",
                    tooltipFillColor: "rgba(51, 51, 51, 0.55)",
                    data:
                    {
                        labels: ["Abancay", "Andahuaylas", "Antabamba", "Aymaraes", "Contabambas", "Chincheros", "Grau"],
                        datasets: [
                        {
                            data: [cantidadPIPAbancay, cantidadPIPAndahuaylas, cantidadPIPAntabamba, cantidadPIPAymaraes, cantidadPIPChincheros, cantidadPIPCotabambas, cantidadPIPGrau],
                            backgroundColor: ["#3498DB", "#9B59B6", "#E74C3C", "#26B99A", "#B6CBD6", "#708B99", "#52C5E1"],
                            hoverBackgroundColor: ["#3498DB", "#B370CF", "#E95E4F", "#36CAAB", "#BDD3DF", "#7C96A3", "#52C5E1"]
                        }]
                    },
                    options: { legend: !1, responsive: !1 }
                };

                $(".canvasDoughnut1").each(function()
                {
                    var b=$(this);

                    new Chart(b, a)
                });
            }
        }
    });
}

var EstadistMontosPipProv=function()
{
    var MontosPipProv=new Array();

    var html1='';

    $.ajax(
    {
        "url": base_url+"index.php/PrincipalPmi/EstadisticaMontoPipProvincias",
        success: function(respuesta)
        {
            var registros=eval(respuesta);

            var suma=0;

            html1+='
'
				+'
'
					+'
Provincia
	'
					+'
Estadistica
	'
					+'
Montos
	'
				+'
'
			+'
'
			+'
';

            for(var i=0; i<registros.length; i++)
            {
                MontosPipProv[i]=registros[i]["MontoProyecto"]; //OPCIONAL, SIRVE PARA IMPRIR LOS MONTOS  EN DATOS PIP PROYECTOS POR PROVINCIA EN LOS DIV

                suma=MontosPipProv[i]+suma; //TOTAL MONTO PROYECTOS EN CABECERA

                html1+='
'
						+''+registros[i]['provincia']+'	'
						+'

	'
						+''+registros[i]['MontoProyecto']+'	'
				+'
';
            }

            html1+="
";

            $("#table-estaditMontPIPProv").html(html1);

            $("#MontoPipAbancay").html(MontosPipProv[0]); // MONTO TOTAL DE ABANCAY EN EL DIV MontoPipAbancay
            $("#MontoPipAndahuaylas").html(MontosPipProv[1]);
            $("#MontoPipAntabamba").html(MontosPipProv[2]);
            $("#MontoPipAymaraes").html(MontosPipProv[3]);
            $("#MontoPipChincheros").html(MontosPipProv[4]);
            $("#MontoPipCotabambas").html(MontosPipProv[5]);
            $("#MontoPipGrau").html(MontosPipProv[6]);
            $("#MontoTotalPip").html(suma); //OBTENER EL MONTO TOTAL DE PROYECTOS EN LA CABECERA
        }
    });
}

function EstadisticasPorCiclosInversion() {
    $.ajax({
        url: base_url+"index.php/PrincipalPmi/EstadisticaPipEstadoCiclo",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);
            var sql='';
            var NumProyectos=0;
            var total_proyectos=registros[0]["Num_Total"];
            var total_otros=registros[0]["TotalNoCiclo"];
            var panel_estadistica=$("#panel_estadistica_ciclo_inversion");
            var porcentaje=0.00;
            for (var i=0; i<registros.length; i++)
            {
                NumProyectos=registros[i]["Num_Proyectos"];
                porcentaje=Math.round((NumProyectos / total_proyectos) * 100);
                sql='
'
					+'
'
						+''+(registros[i]['nombre_estado_ciclo'].charAt(0).toUpperCase())+(registros[i]['nombre_estado_ciclo'].toLowerCase().substring(1))+''
					+'
'
					+'
'
						+'
'
							+'
'
								+porcentaje+'%'
							+'
'
						+'
'
					+'
'
					+'
'
						+''+NumProyectos+''
					+'
'
				+'
';

                panel_estadistica.append(sql);
            }

            porcentaje=Math.round((total_otros/total_proyectos)*100);

            sql='
'
				+'
'
					+'Otros'
				+'
'
				+'
'
					+'
'
						+'
'
						+porcentaje+'%'
						+'
'
					+'
'
				+'
'
				+'
'
					+''+total_otros+''
				+'
'
			+'
';

            panel_estadistica.append(sql);
        }
    });
}

function initMap()
{
    //var LatLng={lat: -25.363, lng: 131.044};
    var map=new google.maps.Map(document.getElementById('map'),
    {
        zoom: 8,
        center: {lat: -14, lng: -73}
        //disableDefaultUI: true
    });

    $.ajax(
    {
        url: base_url+"index.php/PrincipalPmi/GetDatosUbicacion",
        type: "POST",
        success: function(respuesta)
        {
            var registros=eval(respuesta);

            var marker;

            for(var i=0; i<registros.length; i++)
            {
                marker=new google.maps.Marker(
                {
                    position: { lat : registros[i]["latitud"], lng: registros[i]["longitud"] },
                    map : map,
                    title : registros[i]["distrito"]+": "+registros[i]["nombre_pi"]
                });
            }
        }
    });
}

$(document).on('ready', function()
{
    EstaProyProvincia();
    MontoProgramadoPip();
    EstadistMontosPipProv();
    EstadisticasPorCiclosInversion();
});<|endoftext|>


<commit_before>(function() {
	var $blurb = getElementByClassName('blurb');
	$blurb.innerHTML('THis is an IE9 test');
});<commit_msg>cross browser compatibility<commit_after>(function() {
	var blurb = getElementsByClassName('blurb');
	blurb.innerHTML('THis is an IE9 test');
});<|endoftext|>


<commit_before>/*
	Pour info, depuis qu'on utilise le nouveau design Tango
	on utilise aussi le floopDrawerRight.js
	floopDrawer.js n'est plus utilisé
*/

//liste des types à afficher avec leurs icons
var floopContactTypes = [	{ name : "projects", 		color: "purple"	, icon:"lightbulb-o"	},
							{ name : "events", 			color: "orange"	, icon:"calendar"		},
							{ name : "people",  		color: "yellow"	, icon:"user"			},
							{ name : "organizations", 	color: "green" 	, icon:"group"			}];

var openPanelType = { 	"people" 		 : "person",
						"organizations"  : "organization",
						"projects" 	 	 : "project",
						"events" 		 : "event",
					};

var tooltips_lbl = { 	"people" 		  : "Ajouter quelqu'un à votre répertoire.",
						"organizations"   : "Créer une nouvelle organisation",
						"projects" 	 	  : "Créer un nouveau projet",
						"projectsHistory" : "Afficher/Cacher les vieux projets",
						"events" 		  : "Créer un nouvel événement",
						"eventsHistory"   : "Afficher/Cacher les vieux événements",
					};

var floopTypeUsed = new Array();
var floopShowLock = false;
var timeoutShowFloopDrawer = false;

var floopContacts;

function getFloopContacts(){ return floopContacts; }

function buildListContactHtml(contacts, myId){

	floopContacts = contacts;

	var HTML = 			'
'+
							''+
								//t("My directory")+
								' '+
							''+
							'

' +
							'<button id="btnFloopClose"></button>' +

						'
';
		HTML += 		'
' ;

							$.each(floopContactTypes, function(key, type){

							var n=0;
							//compte le nombre d'élément à afficher
							$.each(contacts[type.name], function(key2, value){ n++; });
							//si aucun élément, on affiche pas cette section
							//if(n > 0){
							var urlBtnAdd = "";
							if(type.name == "people") 		 urlBtnAdd = "openForm( 'person')";
							if(type.name == "organizations") urlBtnAdd = "openForm( 'organization')";
							if(type.name == "events") 		 urlBtnAdd = "openForm( 'event')";
							if(type.name == "projects") 	 urlBtnAdd = "openForm( 'project')";

							floopTypeUsed.push(type);

		HTML += 			'
  '+
								'
';
		HTML += 					'
'+
										//'<button onclick="'+urlBtnAdd+'" class="tooltips btn btn-default btn-sm pull-right btn_shortcut_add bg-'+type.color+'" data-placement="left" data-original-title="'+tooltips_lbl[type.name]+'">'+
										//	''+
										//'</button>' +
										' '+t('My '+type.name)+"";
										if(myId != ""){
		HTML += 						'<button onclick="'+urlBtnAdd+'" class="tooltips btn btn-default btn-sm pull-right btn_shortcut_add text-'+type.color+'" data-placement="left" data-original-title="'+tooltips_lbl[type.name]+'">'+
											''+
										'</button>';
											if (type.name == "events" || type.name == "projects") {
		HTML += 						'<button onclick="showHideOldElements(\''+type.name+'\')" class="tooltips btn btn-default btn-sm pull-right btn_shortcut_add text-'+type.color+'" data-placement="left" data-original-title="'+tooltips_lbl[type.name+'History']+'">'+
											''+
										'</button>';
											}
										}
		HTML += 					'
'+
								'
'+
								'
'+
									'
'+
										'
';
										if($(contacts[type.name]).size() == 0){
		HTML += 							' Aucun élément';
										}
										$.each(contacts[type.name], function(key2, value){
		HTML += 							getFloopItem(key2, type, value);
										});
		HTML += 						'
' +
									'
'+
								'
'+
							'
';
							});
		HTML += 		'
' +
						'
'+
					  '
' +
					  '
';
		HTML += '<input type="text" id="search-contact" class="form-control" placeholder="'+t('Search name, postal code, city ...')+'">';

		return HTML;
}

//création HTML d'un élément
function getFloopItem(id, type, value){
	var oldElement = isOldElement(value);

	var cp = (typeof value.address != "undefined" && typeof value.address.postalCode != "undefined") ? value.address.postalCode : typeof value.cp != "undefined" ? value.cp : "";
	var city = (typeof value.address != "undefined" && typeof value.address.addressLocality != "undefined") ? value.address.addressLocality : "";
	defaultImg=type.name;
	if(defaultImg=="people")
		defaultImg="citoyens";
	var profilThumbImageUrl = (typeof value.profilThumbImageUrl != "undefined" && value.profilThumbImageUrl != "") ? baseUrl + value.profilThumbImageUrl : assetPath + "/images/thumb/default_"+defaultImg+".png";
	var id = (typeof value._id != "undefined" && typeof value._id.$id != "undefined") ? value._id.$id : id;
	var path = "#"+openPanelType[type.name]+".detail.id."+id;
	var elementClass = oldElement ? "oldFloopDrawer"+type.name : "";
	var elementStyle = oldElement ? "display:none" : "";

	var HTML = '
' +
					'' +
						'
' +
							''+
							'' +
								'' + value.name + ''+
								'
'+
								'' + cp + ' '+
								'' + city + ''+
							'' +
						'
' +
					'' +
				'
';
	return HTML;
}

var translation = {
		"My people" 		: "Mes contacts",
		"My organizations" 	: "Mes organisations",
		"My projects" 		: "Mes projets",
		"My events" 		: "Mes événements",
		"My directory" 		: "Mon répertoire",
		"Search name, postal code, city ..." : "nom, code postal, ville ..."
}

function t(string){
	if(typeof translation[string] != "undefined"){
		return translation[string];
	}else { return string; }
}
function showFloopDrawer(show){
	if(show){
		if($(".floopDrawer" ).css("display") == "none"){
			$(".floopDrawer").stop().show();
			$(".floopDrawer" ).css("width", 0);
			$(".floopDrawer" ).animate( { width: 300 }, 300 );
		}
	}else{
		$(".floopDrawer").hide("fast");
	}
}
function getFloopContactTypes(type){
	var goodType = null;
	$.each(floopContactTypes, function(key, value){
		if(value.name == type) {
			goodType = value;
		}
	});
	return goodType;
}

function bindEventFloopDrawer(){

	$(".floopDrawer #search-contact").keyup(function(){
		filterFloopDrawer($(this).val());
	});

	//parcourt tous les types de contacts
	$.each(floopContactTypes, function(key, type){
		//initialise le scoll automatique de la liste de contact
		$(".floopHeader #btn-scroll-type-"+type.name).mouseover(function(){

			//var width = $(this).width();
	        //$("#floopDrawerDirectory").css({left:width});
	        //showFloopDrawer(true);
	        var scrollTOP = $('.floopScroll').scrollTop() - $('.floopScroll').position().top +
							$(".floopScroll #scroll-type-"+type.name).position().top;
			$('.floopScroll').scrollTop(scrollTOP);
		});
	});

    $("#ajaxSV,#menu-top-container").mouseenter(function() {
      if(!floopShowLock)
			showFloopDrawer(false);
    });
    $(".floopDrawer, .floopDrawer #search-contact").mouseover(function() {
      showFloopDrawer(true);
    });
    $(".menuIcon.no-floop-item, .box-add, .blockUI, .mapCanvas").mouseover(function() {
      	if(!floopShowLock)
			showFloopDrawer(false);
    });

}

function initFloopScrollByType(){
	var HTML = "";
	$.each(floopTypeUsed, function(key, value){
		var type = value.name; //openPanelType[value.name];
		HTML += "</button>";
	});
	$("#floopScrollByType").html(HTML);
}

//recherche text par nom, cp et city
function filterFloopDrawer(searchVal){
	//masque/affiche tous les contacts présents dans la liste
	if(searchVal != "")	$(".floopDrawer .btn-select-contact").hide();
	else				$(".floopDrawer .btn-select-contact").show();
	//recherche la valeur recherché dans les 3 champs "name", "cp", et "city"
	$.each($(".floopDrawer .name-contact"), function() { checkFloopSearch($(this), searchVal); });
	$.each($(".floopDrawer .cp-contact"),   function() { checkFloopSearch($(this), searchVal); });
	$.each($(".floopDrawer .city-contact"), function() { checkFloopSearch($(this), searchVal); });
}

//si l'élément contient la searchVal, on l'affiche
function checkFloopSearch(thisElement, searchVal, type){
	var content = thisElement.html();
	var found = content.search(new RegExp(searchVal, "i"));
	if(found >= 0){
		var id = thisElement.attr("idcontact");
		$(".floopDrawer #contact"+id).show();
	}
}

//ajout d'un élément dans la liste
function addFloopEntity(entityId, entityType, entityValue){
	//Exception with citoyens collection which is managed like people in display
	if(entityType == "citoyens") entityType = "people";

	//floopContacts[entityType].push(entityValue);

	var type = getFloopContactTypes(entityType);
	//console.log("getFloopContactTypes", entityType, type);

	//We check if the element is already displayed
	if($('#floopItem-'+type.name+'-'+entityId).length < 1){
		console.log("here5");
		var html = getFloopItem(entityId, type, entityValue);
		$("ul#floopType-"+entityType).prepend(html);
	}

	$("ul#floopType-"+entityType+" .no-element").hide();
	floopShowLock = true;
    showFloopDrawer(true);

    setTimeout(function(){
    	if ($('.floopScroll').position().top != null ) {
			var scrollTOP = $('.floopScroll').scrollTop() - $('.floopScroll').position().top +
							$(".floopScroll #scroll-type-"+entityType).position().top;
			$('.floopScroll').scrollTop(scrollTOP);
		}
	}, 1000);

	timeoutShowFloopDrawer = setTimeout(function(){
		floopShowLock = false;
		showFloopDrawer(false);
		clearTimeout(timeoutShowFloopDrawer);
	}, 4000);
	//toastr.success("ajout de l'element floop ok");
}

//ajout d'un élément dans la liste
function removeFloopEntity(entityId, entityType){
	$('#floopItem-'+entityType+'-'+entityId).remove();
}

function showHideOldElements(type) {
	$(".oldFloopDrawer"+type).toggle("slow");
}

// Return true if the endDate of the Element is before the current Date.
function isOldElement(value) {
	var endDate = (typeof value["endDate"] != undefined) ? value["endDate"] : "";
	if (endDate == "") return false;
	return new Date(endDate) < new Date();
}
<commit_msg>correction bug follerw / add member<commit_after>/*
	Pour info, depuis qu'on utilise le nouveau design Tango
	on utilise aussi le floopDrawerRight.js
	floopDrawer.js n'est plus utilisé
*/

//liste des types à afficher avec leurs icons
var floopContactTypes = [	{ name : "projects", 		color: "purple"	, icon:"lightbulb-o"	},
							{ name : "events", 			color: "orange"	, icon:"calendar"		},
							{ name : "people",  		color: "yellow"	, icon:"user"			},
							{ name : "organizations", 	color: "green" 	, icon:"group"			}];

var openPanelType = { 	"people" 		 : "person",
						"organizations"  : "organization",
						"projects" 	 	 : "project",
						"events" 		 : "event",
					};

var tooltips_lbl = { 	"people" 		  : "Ajouter quelqu'un à votre répertoire.",
						"organizations"   : "Créer une nouvelle organisation",
						"projects" 	 	  : "Créer un nouveau projet",
						"projectsHistory" : "Afficher/Cacher les vieux projets",
						"events" 		  : "Créer un nouvel événement",
						"eventsHistory"   : "Afficher/Cacher les vieux événements",
					};

var floopTypeUsed = new Array();
var floopShowLock = false;
var timeoutShowFloopDrawer = false;

var floopContacts;

function getFloopContacts(){ return floopContacts; }

function buildListContactHtml(contacts, myId){

	floopContacts = contacts;

	var HTML = 			'
'+
							''+
								//t("My directory")+
								' '+
							''+
							'

' +
							'<button id="btnFloopClose"></button>' +

						'
';
		HTML += 		'
' ;

							$.each(floopContactTypes, function(key, type){

							var n=0;
							//compte le nombre d'élément à afficher
							$.each(contacts[type.name], function(key2, value){ n++; });
							//si aucun élément, on affiche pas cette section
							//if(n > 0){
							var urlBtnAdd = "";
							if(type.name == "people") 		 urlBtnAdd = "openForm( 'person')";
							if(type.name == "organizations") urlBtnAdd = "openForm( 'organization')";
							if(type.name == "events") 		 urlBtnAdd = "openForm( 'event')";
							if(type.name == "projects") 	 urlBtnAdd = "openForm( 'project')";

							floopTypeUsed.push(type);

		HTML += 			'
  '+
								'
';
		HTML += 					'
'+
										//'<button onclick="'+urlBtnAdd+'" class="tooltips btn btn-default btn-sm pull-right btn_shortcut_add bg-'+type.color+'" data-placement="left" data-original-title="'+tooltips_lbl[type.name]+'">'+
										//	''+
										//'</button>' +
										' '+t('My '+type.name)+"";
										if(myId != ""){
		HTML += 						'<button onclick="'+urlBtnAdd+'" class="tooltips btn btn-default btn-sm pull-right btn_shortcut_add text-'+type.color+'" data-placement="left" data-original-title="'+tooltips_lbl[type.name]+'">'+
											''+
										'</button>';
											if (type.name == "events" || type.name == "projects") {
		HTML += 						'<button onclick="showHideOldElements(\''+type.name+'\')" class="tooltips btn btn-default btn-sm pull-right btn_shortcut_add text-'+type.color+'" data-placement="left" data-original-title="'+tooltips_lbl[type.name+'History']+'">'+
											''+
										'</button>';
											}
										}
		HTML += 					'
'+
								'
'+
								'
'+
									'
'+
										'
';
										if($(contacts[type.name]).size() == 0){
		HTML += 							' Aucun élément';
										}
										$.each(contacts[type.name], function(key2, value){
		HTML += 							getFloopItem(key2, type, value);
										});
		HTML += 						'
' +
									'
'+
								'
'+
							'
';
							});
		HTML += 		'
' +
						'
'+
					  '
' +
					  '
';
		HTML += '<input type="text" id="search-contact" class="form-control" placeholder="'+t('Search name, postal code, city ...')+'">';

		return HTML;
}

//création HTML d'un élément
function getFloopItem(id, type, value){
	var oldElement = isOldElement(value);

	var cp = (typeof value.address != "undefined" && typeof value.address.postalCode != "undefined") ? value.address.postalCode : typeof value.cp != "undefined" ? value.cp : "";
	var city = (typeof value.address != "undefined" && typeof value.address.addressLocality != "undefined") ? value.address.addressLocality : "";
	defaultImg=type.name;
	if(defaultImg=="people")
		defaultImg="citoyens";
	var profilThumbImageUrl = (typeof value.profilThumbImageUrl != "undefined" && value.profilThumbImageUrl != "") ? baseUrl + value.profilThumbImageUrl : assetPath + "/images/thumb/default_"+defaultImg+".png";
	var id = (typeof value._id != "undefined" && typeof value._id.$id != "undefined") ? value._id.$id : id;
	var path = "#"+openPanelType[type.name]+".detail.id."+id;
	var elementClass = oldElement ? "oldFloopDrawer"+type.name : "";
	var elementStyle = oldElement ? "display:none" : "";

	var HTML = '
' +
					'' +
						'
' +
							''+
							'' +
								'' + value.name + ''+
								'
'+
								'' + cp + ' '+
								'' + city + ''+
							'' +
						'
' +
					'' +
				'
';
	return HTML;
}

var translation = {
		"My people" 		: "Mes contacts",
		"My organizations" 	: "Mes organisations",
		"My projects" 		: "Mes projets",
		"My events" 		: "Mes événements",
		"My directory" 		: "Mon répertoire",
		"Search name, postal code, city ..." : "nom, code postal, ville ..."
}

function t(string){
	if(typeof translation[string] != "undefined"){
		return translation[string];
	}else { return string; }
}
function showFloopDrawer(show){
	if(show){
		if($(".floopDrawer" ).css("display") == "none"){
			$(".floopDrawer").stop().show();
			$(".floopDrawer" ).css("width", 0);
			$(".floopDrawer" ).animate( { width: 300 }, 300 );
		}
	}else{
		$(".floopDrawer").hide("fast");
	}
}
function getFloopContactTypes(type){
	var goodType = null;
	$.each(floopContactTypes, function(key, value){
		if(value.name == type) {
			goodType = value;
		}
	});
	return goodType;
}

function bindEventFloopDrawer(){

	$(".floopDrawer #search-contact").keyup(function(){
		filterFloopDrawer($(this).val());
	});

	//parcourt tous les types de contacts
	$.each(floopContactTypes, function(key, type){
		//initialise le scoll automatique de la liste de contact
		$(".floopHeader #btn-scroll-type-"+type.name).mouseover(function(){

			//var width = $(this).width();
	        //$("#floopDrawerDirectory").css({left:width});
	        //showFloopDrawer(true);
	        var scrollTOP = $('.floopScroll').scrollTop() - $('.floopScroll').position().top +
							$(".floopScroll #scroll-type-"+type.name).position().top;
			$('.floopScroll').scrollTop(scrollTOP);
		});
	});

    $("#ajaxSV,#menu-top-container").mouseenter(function() {
      if(!floopShowLock)
			showFloopDrawer(false);
    });
    $(".floopDrawer, .floopDrawer #search-contact").mouseover(function() {
      showFloopDrawer(true);
    });
    $(".menuIcon.no-floop-item, .box-add, .blockUI, .mapCanvas").mouseover(function() {
      	if(!floopShowLock)
			showFloopDrawer(false);
    });

}

function initFloopScrollByType(){
	var HTML = "";
	$.each(floopTypeUsed, function(key, value){
		var type = value.name; //openPanelType[value.name];
		HTML += "</button>";
	});
	$("#floopScrollByType").html(HTML);
}

//recherche text par nom, cp et city
function filterFloopDrawer(searchVal){
	//masque/affiche tous les contacts présents dans la liste
	if(searchVal != "")	$(".floopDrawer .btn-select-contact").hide();
	else				$(".floopDrawer .btn-select-contact").show();
	//recherche la valeur recherché dans les 3 champs "name", "cp", et "city"
	$.each($(".floopDrawer .name-contact"), function() { checkFloopSearch($(this), searchVal); });
	$.each($(".floopDrawer .cp-contact"),   function() { checkFloopSearch($(this), searchVal); });
	$.each($(".floopDrawer .city-contact"), function() { checkFloopSearch($(this), searchVal); });
}

//si l'élément contient la searchVal, on l'affiche
function checkFloopSearch(thisElement, searchVal, type){
	var content = thisElement.html();
	var found = content.search(new RegExp(searchVal, "i"));
	if(found >= 0){
		var id = thisElement.attr("idcontact");
		$(".floopDrawer #contact"+id).show();
	}
}

//ajout d'un élément dans la liste
function addFloopEntity(entityId, entityType, entityValue){
	//Exception with citoyens collection which is managed like people in display
	if(entityType == "citoyens") entityType = "people";

	floopContacts[entityType].push(entityValue);

	var type = getFloopContactTypes(entityType);
	//console.log("getFloopContactTypes", entityType, type);

	//We check if the element is already displayed
	if($('#floopItem-'+type.name+'-'+entityId).length < 1){
		console.log("here5");
		var html = getFloopItem(entityId, type, entityValue);
		$("ul#floopType-"+entityType).prepend(html);
	}

	$("ul#floopType-"+entityType+" .no-element").hide();
	floopShowLock = true;
    showFloopDrawer(true);

    setTimeout(function(){
    	if ($('.floopScroll').position().top != null ) {
			var scrollTOP = $('.floopScroll').scrollTop() - $('.floopScroll').position().top +
							$(".floopScroll #scroll-type-"+entityType).position().top;
			$('.floopScroll').scrollTop(scrollTOP);
		}
	}, 1000);

	timeoutShowFloopDrawer = setTimeout(function(){
		floopShowLock = false;
		showFloopDrawer(false);
		clearTimeout(timeoutShowFloopDrawer);
	}, 4000);
	//toastr.success("ajout de l'element floop ok");
}

//ajout d'un élément dans la liste
function removeFloopEntity(entityId, entityType){
	$('#floopItem-'+entityType+'-'+entityId).remove();
}

function showHideOldElements(type) {
	$(".oldFloopDrawer"+type).toggle("slow");
}

// Return true if the endDate of the Element is before the current Date.
function isOldElement(value) {
	var endDate = (typeof value["endDate"] != undefined) ? value["endDate"] : "";
	if (endDate == "") return false;
	return new Date(endDate) < new Date();
}
<|endoftext|>