<commit_before>(function(env) {
    "use strict";
    env.ddg_spice_seat_geek_sports = function(api_result) {

        if(!api_result || api_result.error || api_result.events.length === 0) {
            return Spice.failed('seat_geek_sports');
        }

        var query = DDG.get_query();
        var clean_query = $.trim(query.replace(/((upcoming\s)?(match(es)?))|(events?)|(schedule)|(sports)/, '').toLowerCase());

        var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];

        Spice.add({
            id: "seat_geek_sports",
            name: "Sports",
            data: api_result.events,
            meta: {
                sourceName: "SeatGeek",
                sourceUrl: "https://seatgeek.com/search?search=" + clean_query,
                sourceIconUrl: "https://seatgeek.com/favicon.ico",
                itemType: "upcoming events"
            },
            normalize: function(item) {
                function getDate(date) {
                    if(date) {
                        // IE 8 and Safari don't support the yyyy-mm-dd date format,
                        // but they support mm/dd/yyyy
                        date = date.replace(/T.*/, '');
                        var remix_date = date.split("-");
                        date = remix_date[1] + "/" + remix_date[2] + "/" + remix_date[0];

                        date = new Date(date);
                        return date;
                    }

                    return;
                }

                function getYear(date) {
                    if(date) {
                        var year = date.getFullYear();
                        return year;
                    }

                    return;
                }

                function getMonth(date) {
                    if(date) {
                        var month = months[parseInt(date.getMonth())];
                        return month;
                    }

                    return;
                }

                function getDay(date) {
                    if(date) {
                        var day = date.getDate();
                        return DDG.getOrdinal(day);
                    }

                    return;
                }

                // Return a logo for this performer if available
                function getLogo(performer, taxonomies) {
                    performer = performer.toLowerCase().replace("vs. ", "").replace(/\s/g, "_");
                    for(var i = 0; i < taxonomies.length; i++) {
                        if(taxonomies[i].name === "mlb" || taxonomies[i].name === "nba" || taxonomies[i].name === "nfl" || taxonomies[i].name === "nhl") {
                            return DDG.get_asset_path('seat_geek/sports', 'assets/' + taxonomies[i].name + '/' + performer.replace("vs. ", "") + '.gif ');
                        }
                    }

                    return '';
                }

                function getPrice(lowest, highest) {
                    var price = "";

                    if(lowest && highest) {
                        price = "$" + lowest + " - $" + highest;
                    }

                    return price;
                }

                // Find the performer queried for,
                // or return the first of the list
                // if not specified in the query
                function getPerformer(performers) {
                    var performer = performers[0];
                    if(performers.length === 1) {
                        return performer;
                    } else {
                        for(var i = 0; i < performers.length; i++) {
                            // If available, return the opponent team/performer
                            if(performers[i].name.toLowerCase() !== clean_query && performers[i].short_name.toLowerCase() !== clean_query) {
                                performers[i].name = "vs. " + performers[i].name;
                                return performers[i];
                            }
                        }

                        return performer;
                    }
                }

                var performer = getPerformer(item.performers);

                return {
                    url: item.url,
                    price: "$" + item.stats.lowest_price + "+",
                    title: performer.name,
                    place: "@ " + item.venue.name,
                    logo: getLogo(performer.name, item.taxonomies),
                    city: item.venue.city + ", " + item.venue.country,
                    month: getMonth(getDate(item.datetime_local)),
                    day: getDay(getDate(item.datetime_local)),
                    year: getYear(getDate(item.datetime_local))
                };
            },
            templates: {
                group: 'base',
                detail: false,
                item_detail: false,
                options: {
                    content: Spice.seat_geek_sports.item,
                    moreAt: true,
                    rating: false
                }
            }
        });
    };
}(this));<commit_msg>SeatGeek Sports - remove 'vs.' from title<commit_after>(function(env) {
    "use strict";
    env.ddg_spice_seat_geek_sports = function(api_result) {

        if(!api_result || api_result.error || api_result.events.length === 0) {
            return Spice.failed('seat_geek_sports');
        }

        var query = DDG.get_query();
        var clean_query = $.trim(query.replace(/((upcoming\s)?(match(es)?))|(events?)|(schedule)|(sports)/, '').toLowerCase());

        var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];

        Spice.add({
            id: "seat_geek_sports",
            name: "Sports",
            data: api_result.events,
            meta: {
                sourceName: "SeatGeek",
                sourceUrl: "https://seatgeek.com/search?search=" + clean_query,
                sourceIconUrl: "https://seatgeek.com/favicon.ico",
                itemType: "upcoming events"
            },
            normalize: function(item) {
                function getDate(date) {
                    if(date) {
                        // IE 8 and Safari don't support the yyyy-mm-dd date format,
                        // but they support mm/dd/yyyy
                        date = date.replace(/T.*/, '');
                        var remix_date = date.split("-");
                        date = remix_date[1] + "/" + remix_date[2] + "/" + remix_date[0];

                        date = new Date(date);
                        return date;
                    }

                    return;
                }

                function getYear(date) {
                    if(date) {
                        var year = date.getFullYear();
                        return year;
                    }

                    return;
                }

                function getMonth(date) {
                    if(date) {
                        var month = months[parseInt(date.getMonth())];
                        return month;
                    }

                    return;
                }

                function getDay(date) {
                    if(date) {
                        var day = date.getDate();
                        return DDG.getOrdinal(day);
                    }

                    return;
                }

                // Return a logo for this performer if available
                function getLogo(performer, taxonomies) {
                    performer = performer.toLowerCase().replace(/\s/g, "_");
                    for(var i = 0; i < taxonomies.length; i++) {
                        if(taxonomies[i].name === "mlb" || taxonomies[i].name === "nba" || taxonomies[i].name === "nfl" || taxonomies[i].name === "nhl") {
                            return DDG.get_asset_path('seat_geek/sports', 'assets/' + taxonomies[i].name + '/' + performer.replace("vs. ", "") + '.gif ');
                        }
                    }

                    return '';
                }

                function getPrice(lowest, highest) {
                    var price = "";

                    if(lowest && highest) {
                        price = "$" + lowest + " - $" + highest;
                    }

                    return price;
                }

                // Find the performer queried for,
                // or return the first of the list
                // if not specified in the query
                function getPerformer(performers) {
                    var performer = performers[0];
                    if(performers.length === 1) {
                        return performer;
                    } else {
                        for(var i = 0; i < performers.length; i++) {
                            // If available, return the opponent team/performer
                            if(performers[i].name.toLowerCase() !== clean_query && performers[i].short_name.toLowerCase() !== clean_query) {
                                return performers[i];
                            }
                        }

                        return performer;
                    }
                }

                var performer = getPerformer(item.performers);

                return {
                    url: item.url,
                    price: "$" + item.stats.lowest_price + "+",
                    title: performer.name,
                    place: "@ " + item.venue.name,
                    logo: getLogo(performer.name, item.taxonomies),
                    city: item.venue.city + ", " + item.venue.country,
                    month: getMonth(getDate(item.datetime_local)),
                    day: getDay(getDate(item.datetime_local)),
                    year: getYear(getDate(item.datetime_local))
                };
            },
            templates: {
                group: 'base',
                detail: false,
                item_detail: false,
                options: {
                    content: Spice.seat_geek_sports.item,
                    moreAt: true,
                    rating: false
                }
            }
        });
    };
}(this));<|endoftext|>


<commit_before>(function(env) {
    "use strict";
    env.ddg_spice_seat_geek_sports = function(api_result) {

        if(!api_result || api_result.error || api_result.events.length === 0) {
            return Spice.failed('seat_geek_sports');
        }

        var query = DDG.get_query();
        var clean_query = $.trim(query.replace(/((upcoming\s)?(match(es)?))|(events?)|(schedule)|(sports)|(tickets)|(games)/, '').toLowerCase());

        var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

        Spice.add({
            id: "seat_geek_sports",
            name: "Sports",
            data: api_result.events,
            meta: {
                searchTerm: clean_query,
                sourceName: "SeatGeek",
                sourceUrl: "https://seatgeek.com/search?search=" + clean_query,
                sourceIconUrl: "https://seatgeek.com/favicon.ico",
                itemType: "upcoming events"
            },
            normalize: function(item) {
                // Check relevancy of the item.
                // First check if the query matches one of the performers names;
                // if it doesn't, and it's not even relevant to the event title,
                // check relevancy on the taxonomies. If this fails too, return null
                var relevant = false;
                var performer = item.performers[0];
                var both_performers = [];
                var title;
                for(var i = 0; i < item.performers.length; i++) {
                    if(DDG.stringsRelevant(item.performers[i].name.toLowerCase(), clean_query, [], 3, true) || DDG.stringsRelevant(item.performers[i].short_name.toLowerCase(), clean_query, [], 3, true)) {
                        relevant = true;
                    } else {
                        performer = item.performers[i];
                    }

                    both_performers.push(item.performers[i].name);
                }

                if(!relevant) {
                    if(DDG.stringsRelevant(item.short_title, clean_query, [], 3, true)) {
                        relevant = true;
                    } else {
                        for(var i = 0; i < item.taxonomies.length; i++) {
                            if(DDG.stringsRelevant(item.taxonomies[i].name.toLowerCase(), clean_query, [], 3, true)) {
                                relevant = true;
                            }
                        }
                    }

                    if(!relevant) {
                        return null;
                    } else {
                        title = both_performers.join(" vs ");
                    }
                } else {
                    title = performer.name;
                }

                function getDate(date) {
                    if(date) {
                        // IE 8 and Safari don't support the yyyy-mm-dd date format,
                        // but they support mm/dd/yyyy
                        date = date.replace(/T.*/, '');
                        var remix_date = date.split("-");
                        date = remix_date[1] + "/" + remix_date[2] + "/" + remix_date[0];

                        date = new Date(date);
                        return date;
                    }

                    return;
                }

                function getYear(date) {
                    if(date) {
                        var year = date.getFullYear();
                        return year;
                    }

                    return;
                }

                function getMonth(date) {
                    if(date) {
                        var month = months[parseInt(date.getMonth())];
                        return month;
                    }

                    return;
                }

                function getDay(date) {
                    if(date) {
                        var day = date.getDate();
                        return day;
                    }

                    return;
                }

                function getPrice(lowest, highest) {
                    var price = "";

                    if(lowest && highest) {
                        price = "$" + lowest + "+";
                    }

                    return price;
                }

                console.debug(getMonth(getDate(item.datetime_local)));

                return {
                    url: item.url,
                    price: getPrice(item.stats.lowest_price, item.stats.highest_price),
                    title: title,
                    place: item.venue.name,
                    city: item.venue.display_location,
                    year: getYear(getDate(item.datetime_local)),
                    dateBadge: {
                        day: getDay(getDate(item.datetime_local)),
                        month: getMonth(getDate(item.datetime_local))
                    }
                };
            },
            templates: {
                group: 'text',
                detail: false,
                item_detail: false,
                options: {
                    footer: Spice.seat_geek_sports.footer,
                    moreAt: true,
                    rating: false
                },
                variants: {
                    tileTitle: '3line-small',
                    tileFooter: '4line'
                }
            }
        });
    };
}(this));
<commit_msg>remove console.log<commit_after>(function(env) {
    "use strict";
    env.ddg_spice_seat_geek_sports = function(api_result) {

        if(!api_result || api_result.error || api_result.events.length === 0) {
            return Spice.failed('seat_geek_sports');
        }

        var query = DDG.get_query();
        var clean_query = $.trim(query.replace(/((upcoming\s)?(match(es)?))|(events?)|(schedule)|(sports)|(tickets)|(games)/, '').toLowerCase());

        var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

        Spice.add({
            id: "seat_geek_sports",
            name: "Sports",
            data: api_result.events,
            meta: {
                searchTerm: clean_query,
                sourceName: "SeatGeek",
                sourceUrl: "https://seatgeek.com/search?search=" + clean_query,
                sourceIconUrl: "https://seatgeek.com/favicon.ico",
                itemType: "upcoming events"
            },
            normalize: function(item) {
                // Check relevancy of the item.
                // First check if the query matches one of the performers names;
                // if it doesn't, and it's not even relevant to the event title,
                // check relevancy on the taxonomies. If this fails too, return null
                var relevant = false;
                var performer = item.performers[0];
                var both_performers = [];
                var title;
                for(var i = 0; i < item.performers.length; i++) {
                    if(DDG.stringsRelevant(item.performers[i].name.toLowerCase(), clean_query, [], 3, true) || DDG.stringsRelevant(item.performers[i].short_name.toLowerCase(), clean_query, [], 3, true)) {
                        relevant = true;
                    } else {
                        performer = item.performers[i];
                    }

                    both_performers.push(item.performers[i].name);
                }

                if(!relevant) {
                    if(DDG.stringsRelevant(item.short_title, clean_query, [], 3, true)) {
                        relevant = true;
                    } else {
                        for(var i = 0; i < item.taxonomies.length; i++) {
                            if(DDG.stringsRelevant(item.taxonomies[i].name.toLowerCase(), clean_query, [], 3, true)) {
                                relevant = true;
                            }
                        }
                    }

                    if(!relevant) {
                        return null;
                    } else {
                        title = both_performers.join(" vs ");
                    }
                } else {
                    title = performer.name;
                }

                function getDate(date) {
                    if(date) {
                        // IE 8 and Safari don't support the yyyy-mm-dd date format,
                        // but they support mm/dd/yyyy
                        date = date.replace(/T.*/, '');
                        var remix_date = date.split("-");
                        date = remix_date[1] + "/" + remix_date[2] + "/" + remix_date[0];

                        date = new Date(date);
                        return date;
                    }

                    return;
                }

                function getYear(date) {
                    if(date) {
                        var year = date.getFullYear();
                        return year;
                    }

                    return;
                }

                function getMonth(date) {
                    if(date) {
                        var month = months[parseInt(date.getMonth())];
                        return month;
                    }

                    return;
                }

                function getDay(date) {
                    if(date) {
                        var day = date.getDate();
                        return day;
                    }

                    return;
                }

                function getPrice(lowest, highest) {
                    var price = "";

                    if(lowest && highest) {
                        price = "$" + lowest + "+";
                    }

                    return price;
                }

                return {
                    url: item.url,
                    price: getPrice(item.stats.lowest_price, item.stats.highest_price),
                    title: title,
                    place: item.venue.name,
                    city: item.venue.display_location,
                    year: getYear(getDate(item.datetime_local)),
                    dateBadge: {
                        day: getDay(getDate(item.datetime_local)),
                        month: getMonth(getDate(item.datetime_local))
                    }
                };
            },
            templates: {
                group: 'text',
                detail: false,
                item_detail: false,
                options: {
                    footer: Spice.seat_geek_sports.footer,
                    moreAt: true,
                    rating: false
                },
                variants: {
                    tileTitle: '3line-small',
                    tileFooter: '4line'
                }
            }
        });
    };
}(this));
<|endoftext|>


<commit_before>'use strict';

/**
 * @desc service for interacting with the sidebar
 * @file sidebar.service.js
 */
(function () {
    angular
        .module('gnap')
        .factory('sidebarService', sidebarService);

    sidebarService.$inject = ['$translate', 'localStorageService'];

    function sidebarService($translate, localStorageService) {

        var settings = {
            items: [],
            shortcuts: [],
            visible: false,
            collapsed: localStorageService.get('sidebar-collapsed') === 'true'
        };

        return {
            settings: settings,
            setItems: setItems,
            setShortcuts: setShortcuts,
            clearItems: clearItems,
            clearShortcuts: clearShortcuts,
            setSelected: setSelected,
            clearSelected: clearSelected,
            toggleMenu: toggleMenu,
            toggleCollapsed: toggleCollapsed,
            toggleSubmenu: toggleSubmenu
        };

        function setItems(value) {
            resolveTranslations(value);
            settings.items = value;
        }

        function setShortcuts(value) {
            resolveTranslations(value);
            settings.shortcuts = value;
        }

        function clearItems() {
            settings.items = [];
        }

        function clearShortcuts() {
            settings.shortcuts = [];
        }

        function toggleMenu() {
            settings.visible = !settings.visible;
        }

        function toggleCollapsed() {
            settings.collapsed = !settings.collapsed;
            localStorageService.set('sidebar-collapsed', settings.collapsed);
        }

        function toggleSubmenu(parent) {
            var currentOpenState = parent.open;

            collapseSameLevelSubmenus(parent);

            parent.open = !currentOpenState;
        }

        function collapseSameLevelSubmenus(item) {
            var siblings = findSiblings(item);

            for (var siblingIndex = 0; siblingIndex < siblings.length; siblingIndex++) {
                siblings[siblingIndex].open = false;
            }
        }

        function findSiblings(item) {
            if (isRootMenuItem(item)) {
                return settings.items;
            }

            // discover the parent of an item, since we have no .parent link
            var parent = (function findParent(parents, child) {
                for (var parentIndex = 0; parentIndex < parents.length; parentIndex++) {
                    var candidateParent = parents[parentIndex];

                    if (hasChild(candidateParent, child)) {
                        return candidateParent;
                    }

                    if (candidateParent.items) {
                        candidateParent = findParent(candidateParent.items, child);

                        if (candidateParent) {
                            return candidateParent;
                        }
                    }
                }

                return null;
            }(settings.items, item));

            if (parent) {
                return parent.items;
            }

            return [];
        }

        function hasChild(parent, child) {
            if (!parent.items) {
                return false;
            }

            for (var childIndex = 0; childIndex < parent.items.length; childIndex++) {
                if (parent.items[childIndex].key === child.key) {
                    return true;
                }
            }
            return false;
        }

        function isRootMenuItem(item) {
            for (var rootItemIndex = 0; rootItemIndex < settings.items.length; rootItemIndex++) {
                if (settings.items[rootItemIndex].key === item.key) {
                    return true;
                }
            }
            return false;
        }

        function setSelected(path) {
            // parse the path into an array
            /* jshint laxbreak:true */
            var parsedPath = path == null
                                ? []
                                : ((path instanceof Array)
                                    ? path
                                    : path.split('/'));
            /* jshint laxbreak:false */

            // find the item to set as active
            updateActiveState(settings.items, parsedPath);

            function updateActiveState(itemList, pathSegments) {

                for (var itemIndex = 0; itemIndex < itemList.length; itemIndex++) {
                    var item = itemList[itemIndex];

                    item.active = false;
                    item.open = false;

                    if (item.key === pathSegments[0]) {

                        if (pathSegments.length === 1) {
                            // last item in the path segments
                            item.active = true;
                        } else if (item.items) {
                            item.open = true;
                        }
                    }

                    if (item.items) {
                        // item has subitems
                        updateActiveState(item.items, pathSegments.splice(1));
                    }
                }
            }
        }

        function clearSelected() {
            setSelected(null);
        }

        function resolveTranslations(items) {
            for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {
                var item = items[itemIndex];
                if (item.titleTranslationId) {
                    (function (translatable) {
                        $translate(translatable.titleTranslationId).then(function (translation) {
                            translatable._title = translation || translatable.title;
                        });
                    })(item);
                } else {
                    item._title = item.title;
                }

                if (item.items) {
                    resolveTranslations(item.items);
                }
            }
        }
    }
})();
<commit_msg>Forgotten == to ===<commit_after>'use strict';

/**
 * @desc service for interacting with the sidebar
 * @file sidebar.service.js
 */
(function () {
    angular
        .module('gnap')
        .factory('sidebarService', sidebarService);

    sidebarService.$inject = ['$translate', 'localStorageService'];

    function sidebarService($translate, localStorageService) {

        var settings = {
            items: [],
            shortcuts: [],
            visible: false,
            collapsed: localStorageService.get('sidebar-collapsed') === 'true'
        };

        return {
            settings: settings,
            setItems: setItems,
            setShortcuts: setShortcuts,
            clearItems: clearItems,
            clearShortcuts: clearShortcuts,
            setSelected: setSelected,
            clearSelected: clearSelected,
            toggleMenu: toggleMenu,
            toggleCollapsed: toggleCollapsed,
            toggleSubmenu: toggleSubmenu
        };

        function setItems(value) {
            resolveTranslations(value);
            settings.items = value;
        }

        function setShortcuts(value) {
            resolveTranslations(value);
            settings.shortcuts = value;
        }

        function clearItems() {
            settings.items = [];
        }

        function clearShortcuts() {
            settings.shortcuts = [];
        }

        function toggleMenu() {
            settings.visible = !settings.visible;
        }

        function toggleCollapsed() {
            settings.collapsed = !settings.collapsed;
            localStorageService.set('sidebar-collapsed', settings.collapsed);
        }

        function toggleSubmenu(parent) {
            var currentOpenState = parent.open;

            collapseSameLevelSubmenus(parent);

            parent.open = !currentOpenState;
        }

        function collapseSameLevelSubmenus(item) {
            var siblings = findSiblings(item);

            for (var siblingIndex = 0; siblingIndex < siblings.length; siblingIndex++) {
                siblings[siblingIndex].open = false;
            }
        }

        function findSiblings(item) {
            if (isRootMenuItem(item)) {
                return settings.items;
            }

            // discover the parent of an item, since we have no .parent link
            var parent = (function findParent(parents, child) {
                for (var parentIndex = 0; parentIndex < parents.length; parentIndex++) {
                    var candidateParent = parents[parentIndex];

                    if (hasChild(candidateParent, child)) {
                        return candidateParent;
                    }

                    if (candidateParent.items) {
                        candidateParent = findParent(candidateParent.items, child);

                        if (candidateParent) {
                            return candidateParent;
                        }
                    }
                }

                return null;
            }(settings.items, item));

            if (parent) {
                return parent.items;
            }

            return [];
        }

        function hasChild(parent, child) {
            if (!parent.items) {
                return false;
            }

            for (var childIndex = 0; childIndex < parent.items.length; childIndex++) {
                if (parent.items[childIndex].key === child.key) {
                    return true;
                }
            }
            return false;
        }

        function isRootMenuItem(item) {
            for (var rootItemIndex = 0; rootItemIndex < settings.items.length; rootItemIndex++) {
                if (settings.items[rootItemIndex].key === item.key) {
                    return true;
                }
            }
            return false;
        }

        function setSelected(path) {
            // parse the path into an array
            /* jshint laxbreak:true */
            var parsedPath = path === null
                                ? []
                                : ((path instanceof Array)
                                    ? path
                                    : path.split('/'));
            /* jshint laxbreak:false */

            // find the item to set as active
            updateActiveState(settings.items, parsedPath);

            function updateActiveState(itemList, pathSegments) {

                for (var itemIndex = 0; itemIndex < itemList.length; itemIndex++) {
                    var item = itemList[itemIndex];

                    item.active = false;
                    item.open = false;

                    if (item.key === pathSegments[0]) {

                        if (pathSegments.length === 1) {
                            // last item in the path segments
                            item.active = true;
                        } else if (item.items) {
                            item.open = true;
                        }
                    }

                    if (item.items) {
                        // item has subitems
                        updateActiveState(item.items, pathSegments.splice(1));
                    }
                }
            }
        }

        function clearSelected() {
            setSelected(null);
        }

        function resolveTranslations(items) {
            for (var itemIndex = 0; itemIndex < items.length; itemIndex++) {
                var item = items[itemIndex];
                if (item.titleTranslationId) {
                    (function (translatable) {
                        $translate(translatable.titleTranslationId).then(function (translation) {
                            translatable._title = translation || translatable.title;
                        });
                    })(item);
                } else {
                    item._title = item.title;
                }

                if (item.items) {
                    resolveTranslations(item.items);
                }
            }
        }
    }
})();
<|endoftext|>


<commit_before>global.requireRoot = function (name) {
    return require(__dirname + '/' + name);
};

module.exports = function (grunt) {
    var conf = require('./conf');

    var log = conf.log(grunt);
    require('time-grunt')(grunt);

    var pathing = __dirname.indexOf('node_module') >= 0 ? "./../../../" : "./../";
    var build = grunt.file.readJSON(grunt.option('build') || pathing + "build.json");
    var config = grunt.file.readJSON(grunt.option('config') || pathing + "config.json");

    config.directories = config.directories || { root: "" };

    config.directories.root = config.directories.root || pathing;

    grunt.initConfig();
    var tasks = conf.getTasks(build);

    build = conf.prepareBuild(build);

    grunt.config.set("build", build);
    grunt.config.set("config", config);

    log.config();
    conf.loadConfig(config, grunt);
    conf.loadBuild(build, grunt);
    conf.loadTasks(tasks, grunt);

    grunt.registerTask('default', tasks);
};
<commit_msg>joined root path for better readability when debugging<commit_after>global.requireRoot = function (name) {
    return require(__dirname + '/' + name);
};

module.exports = function (grunt) {
    var conf = require('./conf');
    var path = require('path');

    var log = conf.log(grunt);
    require('time-grunt')(grunt);

    var pathing = __dirname.indexOf('node_module') >= 0 ? path.join(__dirname, "./../../../") : path.join(__dirname, "./../");
    var build = grunt.file.readJSON(grunt.option('build') || pathing + "build.json");
    var config = grunt.file.readJSON(grunt.option('config') || pathing + "config.json");

    config.directories = config.directories || { root: "" };

    config.directories.root = config.directories.root || pathing;

    grunt.initConfig();
    var tasks = conf.getTasks(build);

    build = conf.prepareBuild(build);

    grunt.config.set("build", build);
    grunt.config.set("config", config);

    log.config();
    conf.loadConfig(config, grunt);
    conf.loadBuild(build, grunt);
    conf.loadTasks(tasks, grunt);

    grunt.registerTask('default', tasks);
};
<|endoftext|>


<commit_before>import HasOneObject from './links/has-one-object';
import HasManyArray from './links/has-many-array';
import key from 'ember-orbit/fields/key';
import { uuid } from 'orbit/lib/uuid';

/**
 @module ember-orbit
 */

var get = Ember.get;
var set = Ember.set;

/**
 @class Model
 @namespace EO
 */
var Model = Ember.Object.extend(Ember.Evented, {
  primaryId: null,

  getKey: function(field) {
    var store = get(this, 'store');
    var pk = this.constructor.primaryKey;

    if (pk === field) {
      return this.primaryId;
    } else {
      var type = this.constructor.typeKey;
      return store.retrieveKey(type, this.primaryId, field);
    }
  },

  getAttribute: function(field) {
    var store = get(this, 'store');
    var type = this.constructor.typeKey;
    var id = get(this, 'primaryId');

    return store.retrieveAttribute(type, id, field);
  },

  getLink: function(field) {
    var store = get(this, 'store');
    var type = this.constructor.typeKey;
    var id = get(this, 'primaryId');

    var relatedRecord = store.retrieveLink(type, id, field) || null;

    var hasOneObject = HasOneObject.create({
      content: relatedRecord,
      store: store,
      _ownerId: id,
      _ownerType: type,
      _linkField: field
    });

    this._assignLink(field, hasOneObject);

    return hasOneObject;
  },

  getLinks: function(field) {
    var store = get(this, 'store');
    var type = this.constructor.typeKey;
    var id = get(this, 'primaryId');

    var relatedRecords = Ember.A(store.retrieveLinks(type, id, field) || []);

    var hasManyArray = HasManyArray.create({
      content: relatedRecords,
      store: this.store,
      _ownerId: id,
      _ownerType: type,
      _linkField: field
    });

    this._assignLink(field, hasManyArray);

    return hasManyArray;
  },

  patch: function(field, value) {
    var store = get(this, 'store');
    var type = this.constructor.typeKey;

    return store.patch(type, this.primaryId, field, value);
  },

  addLink: function(field, relatedRecord) {
    var store = get(this, 'store');
    var type = this.constructor.typeKey;
    var relatedId = relatedRecord ? relatedRecord.primaryId : null;

    return store.addLink(type, this.primaryId, field, relatedId);
  },

  removeLink: function(field, relatedRecord) {
    var store = get(this, 'store');
    var type = this.constructor.typeKey;
    var relatedId = relatedRecord ? relatedRecord.primaryId : null;

    return store.removeLink(type, this.primaryId, field, relatedId);
  },

  remove: function() {
    var store = get(this, 'store');
    var type = this.constructor.typeKey;

    return store.remove(type, this.primaryId);
  },

  willDestroy: function() {
    this.trigger('didUnload');
    this._super();

    var store = get(this, 'store');
    var type = this.constructor.typeKey;

    store.unload(type, this.primaryId);
  },

  _assignLink: function(field, value) {
    this._links = this._links || {};
    this._links[field] = value;
  }
});

var _create = Model.create;

Model.reopenClass({
  _create: function(store, id) {
    var record = _create.call(this, {store: store});
    set(record, 'primaryId', id);
    return record;
  },

  create: function() {
    throw new Ember.Error("You should not call `create` on a model. Instead, call `store.add` with the attributes you would like to set.");
  },

  primaryKey: Ember.computed('keys', function() {
    if (arguments.length > 1) {
      throw new Ember.Error("You should not set `primaryKey` on a model. Instead, define a `key` with the options `{primaryKey: true, defaultValue: idGenerator}`.");
    }

    var keys = get(this, 'keys');
    var keyNames = Object.keys(keys);
    for (var k in keyNames) {
      var keyName = keyNames[k];
      if (keys[keyName].primaryKey) {
        return keyName;
      }
    }
  }),

  keys: Ember.computed(function() {
    var map = {};
    var _this = this;
    var primaryKey;

    _this.eachComputedProperty(function(name, meta) {
      if (meta.isKey) {
        meta.name = name;
        map[name] = meta.options;
        if (meta.options.primaryKey) {
          primaryKey = name;
        }
      }
    });

    // Set a single primary key named `id` if no other has been defined
    if (!primaryKey) {
      primaryKey = 'id';

      var options = {primaryKey: true, defaultValue: uuid};
      this.reopen({id: key(options)});
      map.id = options;
    }

    return map;
  }),

  attributes: Ember.computed(function() {
    var map = {};

    this.eachComputedProperty(function(name, meta) {
      if (meta.isAttribute) {
        meta.name = name;
        map[name] = meta.options;
      }
    });

    return map;
  }),

  links: Ember.computed(function() {
    var map = {};

    this.eachComputedProperty(function(name, meta) {
      if (meta.isLink) {
        meta.name = name;
        map[name] = meta.options;
      }
    });

    return map;
  })
});

export default Model;
<commit_msg>Use Ember.get for accessing properties - some are computed<commit_after>import HasOneObject from './links/has-one-object';
import HasManyArray from './links/has-many-array';
import key from 'ember-orbit/fields/key';
import { uuid } from 'orbit/lib/uuid';

/**
 @module ember-orbit
 */

var get = Ember.get;
var set = Ember.set;

/**
 @class Model
 @namespace EO
 */
var Model = Ember.Object.extend(Ember.Evented, {
  primaryId: null,

  getKey: function(field) {
    var store = get(this, 'store');
    var pk = get(this.constructor, 'primaryKey');

    if (pk === field) {
      return this.primaryId;
    } else {
      var type = get(this.constructor, 'typeKey');
      return store.retrieveKey(type, this.primaryId, field);
    }
  },

  getAttribute: function(field) {
    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');
    var id = get(this, 'primaryId');

    return store.retrieveAttribute(type, id, field);
  },

  getLink: function(field) {
    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');
    var id = get(this, 'primaryId');

    var relatedRecord = store.retrieveLink(type, id, field) || null;

    var hasOneObject = HasOneObject.create({
      content: relatedRecord,
      store: store,
      _ownerId: id,
      _ownerType: type,
      _linkField: field
    });

    this._assignLink(field, hasOneObject);

    return hasOneObject;
  },

  getLinks: function(field) {
    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');
    var id = get(this, 'primaryId');

    var relatedRecords = Ember.A(store.retrieveLinks(type, id, field) || []);

    var hasManyArray = HasManyArray.create({
      content: relatedRecords,
      store: this.store,
      _ownerId: id,
      _ownerType: type,
      _linkField: field
    });

    this._assignLink(field, hasManyArray);

    return hasManyArray;
  },

  patch: function(field, value) {
    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');

    return store.patch(type, this.primaryId, field, value);
  },

  addLink: function(field, relatedRecord) {
    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');
    var relatedId = relatedRecord ? relatedRecord.primaryId : null;

    return store.addLink(type, this.primaryId, field, relatedId);
  },

  removeLink: function(field, relatedRecord) {
    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');
    var relatedId = relatedRecord ? relatedRecord.primaryId : null;

    return store.removeLink(type, this.primaryId, field, relatedId);
  },

  remove: function() {
    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');

    return store.remove(type, this.primaryId);
  },

  willDestroy: function() {
    this.trigger('didUnload');
    this._super();

    var store = get(this, 'store');
    var type = get(this.constructor, 'typeKey');

    store.unload(type, this.primaryId);
  },

  _assignLink: function(field, value) {
    this._links = this._links || {};
    this._links[field] = value;
  }
});

var _create = Model.create;

Model.reopenClass({
  _create: function(store, id) {
    var record = _create.call(this, {store: store});
    set(record, 'primaryId', id);
    return record;
  },

  create: function() {
    throw new Ember.Error("You should not call `create` on a model. Instead, call `store.add` with the attributes you would like to set.");
  },

  primaryKey: Ember.computed('keys', function() {
    if (arguments.length > 1) {
      throw new Ember.Error("You should not set `primaryKey` on a model. Instead, define a `key` with the options `{primaryKey: true, defaultValue: idGenerator}`.");
    }

    var keys = get(this, 'keys');
    var keyNames = Object.keys(keys);
    for (var k in keyNames) {
      var keyName = keyNames[k];
      if (keys[keyName].primaryKey) {
        return keyName;
      }
    }
  }),

  keys: Ember.computed(function() {
    var map = {};
    var _this = this;
    var primaryKey;

    _this.eachComputedProperty(function(name, meta) {
      if (meta.isKey) {
        meta.name = name;
        map[name] = meta.options;
        if (meta.options.primaryKey) {
          primaryKey = name;
        }
      }
    });

    // Set a single primary key named `id` if no other has been defined
    if (!primaryKey) {
      primaryKey = 'id';

      var options = {primaryKey: true, defaultValue: uuid};
      this.reopen({id: key(options)});
      map.id = options;
    }

    return map;
  }),

  attributes: Ember.computed(function() {
    var map = {};

    this.eachComputedProperty(function(name, meta) {
      if (meta.isAttribute) {
        meta.name = name;
        map[name] = meta.options;
      }
    });

    return map;
  }),

  links: Ember.computed(function() {
    var map = {};

    this.eachComputedProperty(function(name, meta) {
      if (meta.isLink) {
        meta.name = name;
        map[name] = meta.options;
      }
    });

    return map;
  })
});

export default Model;
<|endoftext|>


<commit_before>/*!
 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
 *
 * HTTP endpoints for interacting with compute nodes.
 *
 */

var async = require('async');
var restify = require('restify');
var fs = require('fs');
var util = require('util');
var sprintf = require('sprintf').sprintf;
var validation = require('../validation/endpoints');

var ModelServer = require('../models/server');
var ModelPlatform = require('../models/platform');
var datasetEndpoints = require('./zfs');
var common = require('../common');
var verror = require('verror');

function Server() {}

Server.init = function () {
    Server.log = ModelServer.log;
};

/**
 * Returns Servers present in datacenter.
 *
 * @name ServerList
 * @endpoint GET /servers
 * @section Servers
 *
 * @param {String} uuids Comma seperated list of UUIDs to look up
 * @param {Boolean} setup Return only setup servers
 * @param {Boolean} headnode Return only headnodes
 *
 * @example GET /servers
 * @example GET /servers?uuids=uuid1,uuid2
 * @example GET /servers?setup=true
 * @example GET /servers?headnode=false
 *
 * @response 200 Array The returned servers
 */

Server.list = function (req, res, next) {
    var result;

    var rules = {
        'setup': [
            ['optional', undefined],
            ['regex', RegExp(/^(true|false)$/i)],
            ['sanitize', 'toBoolean']
        ],
        'headnode': [
            ['optional', undefined],
            ['regex', RegExp(/^(true|false)$/i)],
            ['sanitize', 'toBoolean']
        ],
        'uuids': [
            ['optional', undefined],
            /*JSSTYLED*/
            ['regex', RegExp(/^(\w+),+\w+$/i)]
        ]
    };

    try {
        validation.ensureParamsValid(req, res, rules);
    }
    catch (e) {
        next(e);
        return;
    }

    async.waterfall([
        function (wf$callback) {
            var options = {};
            options.wantFinal = true;

            options.uuid = req.params.uuids &&
                req.params.uuids.split(new RegExp('\s*,\s*', 'g'));
            options.setup = req.params.setup;
            options.headnode = req.params.headnode;
            options.default = false;

            req.log.info(options, 'Searching for all servers');
            ModelServer.list(
                options,
                function (error, s) {
                    if (error) {
                        wf$callback(error);
                        return;
                    }
                    req.log.info(util.inspect(s), 'Servers found');
                    result = s;
                    wf$callback();
                    return;
                });
        }
    ],
    function (error) {
        if (error) {
            next(
                new restify.InternalError(error.message));
            return;
        }

        res.send(result);
        next();
        return;
    });
};

/**
 * Look up a single Server by UUID.
 *
 * @name ServerGet
 * @endpoint GET /servers/:server\_uuid
 * @section Servers
 *
 * @example GET /servers/12494d5e-3960-4d65-a61a-0ca6252d6914
 *
 * @response 200 Object The server object>
 */

Server.get = function (req, res, next) {
    req.stash.server.getFinal(function (error, server) {
        res.send(server);
        next();
    });
};

/**
 * Set the value of a Server's attribute.
 *
 * @name ServerUpdate
 * @endpoint POST /servers/:server_uuid
 * @section Servers
 *
 * @param {String} boot_platform The platform image to be used on next boot
 * @param {String} default_console Console type
 * @param {String} rack_identifier The id of the server's rack
 * @param {Boolean} reserved Server is available for provisioning
 * @param {String} serial Serial device
 * @param {Number} serial_speed Serial speed value
 * @param {Boolean} setup True if server has been set up
 * @param {Boolean} setting_up True if server is in the process of setting up
 * @param {String} traits Server traits
 *
 * @example POST /servers/12494d5e-3960-4d65-a61a
 *          -d '{ "default_console": "vga", "setup", true }'
 *
 * @response 204 None The value was set successfuly
 */

Server.update = function (req, res, next) {
    var rules = {
        'boot_platform': ['optional', 'isStringType', 'isTrim'],
        'boot_params': ['optional', 'isObjectType'],
        'default_console': ['optional', 'isStringType', 'isTrim'],
        'rack_identifier': ['optional', 'isStringType', 'isTrim'],
        'reserved': ['optional', 'isBooleanType'],
        'serial': ['optional', 'isStringType', 'isTrim'],
        'serial_speed': ['optional', 'isNumber', 'isTrim'],
        'setup': ['optional', 'isBooleanType'],
        'setting_up': ['optional', 'isBooleanType'],
        'traits': ['optional', 'isObjectType']
    };

    try {
        validation.ensureParamsValid(req, res, rules);
    }
    catch (e) {
        next(e);
        return;
    }

    var attrs = [
        ['boot_platform', String],
        ['boot_params', Object],
        ['default_console', String],
        ['reserved', Boolean],
        ['serial', String],
        ['serial_speed', Number],
        ['setup', Boolean],
        ['setting_up', Boolean],
        ['traits', Object],
        ['rack_identifier', String]
    ];

    var change = {};

    attrs.forEach(function (i) {
        var param = i[0];
        var type =  i[1];
        var val = req.params[param];

        if (typeof (val) === 'undefined') {
            return;
        }

        if (type == String) {
            change[param] = val;
        } else if (type == Boolean) {
            if (val === true) {
                change[param] = true;
            } else if (val === false) {
                change[param] = false;
            }
        } else if (type == Number) {
            change[param] = Number(val);
        } else {
            change[param] = val;
        }
    });

    // If specified, ensure the boot_platform exists
    if (change.boot_platform) {
        ModelPlatform.list({}, function (error, platforms) {
            if (error) {
                next(
                    new restify.InternalError(error.message));
                return;
            }

            if (!platforms.hasOwnProperty(change.boot_platform)) {
                next(new restify.InternalError(
                    'Platform %s does not exist', change.boot_platform));
                return;
            } else {
                modify();
            }
        });
    } else {
        modify();
    }

    function modify() {
        req.stash.server.modify(
            change,
            function (error) {
                if (error) {
                    next(new restify.InternalError(error.message));
                    return;
                }

                res.send(204);
                next();
                return;
            });
    }
};

/**
 * Reset the server back to a factory state.
 *
 * @name ServerFactoryReset
 * @endpoint PUT /servers/:server\_uuid/factory-reset
 * @section Servers
 *
 * @response 204 Object Setup initated, returns object containing workflow id
 * @response 500 None Error attempting to set up server
 */

Server.factoryReset = function (req, res, next) {
    req.stash.server.cacheGetVms(function (error, vms) {
        if (error) {
            next(new restify.InternalError(error.message));
            return;
        }

        if (vms && Object.keys(vms).length) {
            res.send(
                403, 'Server may not be reset because it has ' +
                Object.keys(vms).length +
                ' vms');
            next();
            return;
        } else {
            req.log.info(
                '%s had no VMs prior to factory-reset. Continuing.',
                req.stash.server.uuid);
        }

        req.stash.server.factoryReset(function (resetError, jobUuid) {
            if (resetError) {
                next(new restify.InternalError(resetError.message));
                return;
            }

            setTimeout(function () {
                req.stash.server.cacheDelVms(function () {});
            }, 10000);

            res.send(202, { job_uuid: jobUuid });
            next();
        });

    });
};

/**
 * Initiate the server setup process for a newly started server.
 *
 * @name ServerSetup
 * @endpoint PUT /servers/:server_uuid/setup
 * @section Servers
 *
 * @response 200 Object Setup initated, returns object containing workflow id
 * @response 500 None Error while processing request
 */

Server.setup = function (req, res, next) {
    req.stash.server.getRaw(function (error, rawserver) {
        if (rawserver.setup) {
            res.send(204);
            next();
            return;
        }

        req.stash.server.setup(function (setupError, jobUuid) {
            if (setupError) {
                next(
                    new restify.InternalError(
                        setupError.message));
                return;
            }
            res.send(202, { job_uuid: jobUuid });
            next();
            return;
        });
    });
};

/**
 * Remove all references to given server. Does not change anything on the
 * actual server.
 *
 * @name ServerDelete
 * @endpoint DELETE /servers/:server_uuid
 * @section Servers
 *
 * @response 204 None Server was deleted successfully
 * @response 500 Error Could not process request
 */

Server.del = function (req, res, next) {
    req.stash.server.del(function (error) {
        if (error) {
            next(
                new restify.InternalError(error.message));
            return;
        }
        res.send(200);
        next();
    });
};

function attachTo(http, model) {
    Server.init();

    var ensure = require('../endpoints').ensure;

    var listBefore = ensure({
        connectionTimeoutSeconds: 60 * 60,
        model: model,
        connected: ['amqp', 'moray', 'redis', 'workflow']
    });

    var getBefore = ensure({
        connectionTimeoutSeconds: 60 * 60,
        model: model,
        prepopulate: ['server'],
        connected: ['amqp', 'moray', 'redis', 'workflow']
    });

    // List servers
    http.get(
        { path: '/servers', name: 'ServerList' },
        listBefore, Server.list);

    // Get server
    http.get(
        { path: '/servers/:server_uuid', name: 'ServerGet' },
        getBefore, Server.get);

    // Update server
    http.post(
        { path: '/servers/:server_uuid', name: 'ServerUpdate' },
        getBefore, Server.update);

    // Setup server
    http.put(
        { path: '/servers/:server_uuid/setup', name: 'ServerSetup' },
        getBefore, Server.setup);

    // Setup server
    http.del(
        { path: '/servers/:server_uuid', name: 'ServerDelete' },
        getBefore, Server.del);

    // Factory-reset server
    http.put({
        path: '/servers/:server_uuid/factory-reset',
        name: 'ServerFactoryReset' },
        getBefore, Server.factoryReset);
}

exports.attachTo = attachTo;
<commit_msg>CNAPI-205: Improve regex matching for multiple comma-seperated uuids<commit_after>/*!
 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
 *
 * HTTP endpoints for interacting with compute nodes.
 *
 */

var async = require('async');
var restify = require('restify');
var fs = require('fs');
var util = require('util');
var sprintf = require('sprintf').sprintf;
var validation = require('../validation/endpoints');

var ModelServer = require('../models/server');
var ModelPlatform = require('../models/platform');
var datasetEndpoints = require('./zfs');
var common = require('../common');
var verror = require('verror');

function Server() {}

Server.init = function () {
    Server.log = ModelServer.log;
};

/**
 * Returns Servers present in datacenter.
 *
 * @name ServerList
 * @endpoint GET /servers
 * @section Servers
 *
 * @param {String} uuids Comma seperated list of UUIDs to look up
 * @param {Boolean} setup Return only setup servers
 * @param {Boolean} headnode Return only headnodes
 *
 * @example GET /servers
 * @example GET /servers?uuids=uuid1,uuid2
 * @example GET /servers?setup=true
 * @example GET /servers?headnode=false
 *
 * @response 200 Array The returned servers
 */

Server.list = function (req, res, next) {
    var result;

    var rules = {
        'setup': [
            ['optional', undefined],
            ['regex', RegExp(/^(true|false)$/i)],
            ['sanitize', 'toBoolean']
        ],
        'headnode': [
            ['optional', undefined],
            ['regex', RegExp(/^(true|false)$/i)],
            ['sanitize', 'toBoolean']
        ],
        'uuids': [
            ['optional', undefined],
            /*JSSTYLED*/
            ['regex', RegExp(/^[-a-z0-9A-Z]+(,[-a-z0-9A-Z]+)*$/i)]
        ]
    };

    try {
        validation.ensureParamsValid(req, res, rules);
    }
    catch (e) {
        next(e);
        return;
    }

    async.waterfall([
        function (wf$callback) {
            var options = {};
            options.wantFinal = true;

            options.uuid = req.params.uuids &&
                req.params.uuids.split(new RegExp('\s*,\s*', 'g'));
            options.setup = req.params.setup;
            options.headnode = req.params.headnode;
            options.default = false;

            req.log.info(options, 'Searching for all servers');
            ModelServer.list(
                options,
                function (error, s) {
                    if (error) {
                        wf$callback(error);
                        return;
                    }
                    req.log.info(util.inspect(s), 'Servers found');
                    result = s;
                    wf$callback();
                    return;
                });
        }
    ],
    function (error) {
        if (error) {
            next(
                new restify.InternalError(error.message));
            return;
        }

        res.send(result);
        next();
        return;
    });
};

/**
 * Look up a single Server by UUID.
 *
 * @name ServerGet
 * @endpoint GET /servers/:server\_uuid
 * @section Servers
 *
 * @example GET /servers/12494d5e-3960-4d65-a61a-0ca6252d6914
 *
 * @response 200 Object The server object>
 */

Server.get = function (req, res, next) {
    req.stash.server.getFinal(function (error, server) {
        res.send(server);
        next();
    });
};

/**
 * Set the value of a Server's attribute.
 *
 * @name ServerUpdate
 * @endpoint POST /servers/:server_uuid
 * @section Servers
 *
 * @param {String} boot_platform The platform image to be used on next boot
 * @param {String} default_console Console type
 * @param {String} rack_identifier The id of the server's rack
 * @param {Boolean} reserved Server is available for provisioning
 * @param {String} serial Serial device
 * @param {Number} serial_speed Serial speed value
 * @param {Boolean} setup True if server has been set up
 * @param {Boolean} setting_up True if server is in the process of setting up
 * @param {String} traits Server traits
 *
 * @example POST /servers/12494d5e-3960-4d65-a61a
 *          -d '{ "default_console": "vga", "setup", true }'
 *
 * @response 204 None The value was set successfuly
 */

Server.update = function (req, res, next) {
    var rules = {
        'boot_platform': ['optional', 'isStringType', 'isTrim'],
        'boot_params': ['optional', 'isObjectType'],
        'default_console': ['optional', 'isStringType', 'isTrim'],
        'rack_identifier': ['optional', 'isStringType', 'isTrim'],
        'reserved': ['optional', 'isBooleanType'],
        'serial': ['optional', 'isStringType', 'isTrim'],
        'serial_speed': ['optional', 'isNumber', 'isTrim'],
        'setup': ['optional', 'isBooleanType'],
        'setting_up': ['optional', 'isBooleanType'],
        'traits': ['optional', 'isObjectType']
    };

    try {
        validation.ensureParamsValid(req, res, rules);
    }
    catch (e) {
        next(e);
        return;
    }

    var attrs = [
        ['boot_platform', String],
        ['boot_params', Object],
        ['default_console', String],
        ['reserved', Boolean],
        ['serial', String],
        ['serial_speed', Number],
        ['setup', Boolean],
        ['setting_up', Boolean],
        ['traits', Object],
        ['rack_identifier', String]
    ];

    var change = {};

    attrs.forEach(function (i) {
        var param = i[0];
        var type =  i[1];
        var val = req.params[param];

        if (typeof (val) === 'undefined') {
            return;
        }

        if (type == String) {
            change[param] = val;
        } else if (type == Boolean) {
            if (val === true) {
                change[param] = true;
            } else if (val === false) {
                change[param] = false;
            }
        } else if (type == Number) {
            change[param] = Number(val);
        } else {
            change[param] = val;
        }
    });

    // If specified, ensure the boot_platform exists
    if (change.boot_platform) {
        ModelPlatform.list({}, function (error, platforms) {
            if (error) {
                next(
                    new restify.InternalError(error.message));
                return;
            }

            if (!platforms.hasOwnProperty(change.boot_platform)) {
                next(new restify.InternalError(
                    'Platform %s does not exist', change.boot_platform));
                return;
            } else {
                modify();
            }
        });
    } else {
        modify();
    }

    function modify() {
        req.stash.server.modify(
            change,
            function (error) {
                if (error) {
                    next(new restify.InternalError(error.message));
                    return;
                }

                res.send(204);
                next();
                return;
            });
    }
};

/**
 * Reset the server back to a factory state.
 *
 * @name ServerFactoryReset
 * @endpoint PUT /servers/:server\_uuid/factory-reset
 * @section Servers
 *
 * @response 204 Object Setup initated, returns object containing workflow id
 * @response 500 None Error attempting to set up server
 */

Server.factoryReset = function (req, res, next) {
    req.stash.server.cacheGetVms(function (error, vms) {
        if (error) {
            next(new restify.InternalError(error.message));
            return;
        }

        if (vms && Object.keys(vms).length) {
            res.send(
                403, 'Server may not be reset because it has ' +
                Object.keys(vms).length +
                ' vms');
            next();
            return;
        } else {
            req.log.info(
                '%s had no VMs prior to factory-reset. Continuing.',
                req.stash.server.uuid);
        }

        req.stash.server.factoryReset(function (resetError, jobUuid) {
            if (resetError) {
                next(new restify.InternalError(resetError.message));
                return;
            }

            setTimeout(function () {
                req.stash.server.cacheDelVms(function () {});
            }, 10000);

            res.send(202, { job_uuid: jobUuid });
            next();
        });

    });
};

/**
 * Initiate the server setup process for a newly started server.
 *
 * @name ServerSetup
 * @endpoint PUT /servers/:server_uuid/setup
 * @section Servers
 *
 * @response 200 Object Setup initated, returns object containing workflow id
 * @response 500 None Error while processing request
 */

Server.setup = function (req, res, next) {
    req.stash.server.getRaw(function (error, rawserver) {
        if (rawserver.setup) {
            res.send(204);
            next();
            return;
        }

        req.stash.server.setup(function (setupError, jobUuid) {
            if (setupError) {
                next(
                    new restify.InternalError(
                        setupError.message));
                return;
            }
            res.send(202, { job_uuid: jobUuid });
            next();
            return;
        });
    });
};

/**
 * Remove all references to given server. Does not change anything on the
 * actual server.
 *
 * @name ServerDelete
 * @endpoint DELETE /servers/:server_uuid
 * @section Servers
 *
 * @response 204 None Server was deleted successfully
 * @response 500 Error Could not process request
 */

Server.del = function (req, res, next) {
    req.stash.server.del(function (error) {
        if (error) {
            next(
                new restify.InternalError(error.message));
            return;
        }
        res.send(200);
        next();
    });
};

function attachTo(http, model) {
    Server.init();

    var ensure = require('../endpoints').ensure;

    var listBefore = ensure({
        connectionTimeoutSeconds: 60 * 60,
        model: model,
        connected: ['amqp', 'moray', 'redis', 'workflow']
    });

    var getBefore = ensure({
        connectionTimeoutSeconds: 60 * 60,
        model: model,
        prepopulate: ['server'],
        connected: ['amqp', 'moray', 'redis', 'workflow']
    });

    // List servers
    http.get(
        { path: '/servers', name: 'ServerList' },
        listBefore, Server.list);

    // Get server
    http.get(
        { path: '/servers/:server_uuid', name: 'ServerGet' },
        getBefore, Server.get);

    // Update server
    http.post(
        { path: '/servers/:server_uuid', name: 'ServerUpdate' },
        getBefore, Server.update);

    // Setup server
    http.put(
        { path: '/servers/:server_uuid/setup', name: 'ServerSetup' },
        getBefore, Server.setup);

    // Setup server
    http.del(
        { path: '/servers/:server_uuid', name: 'ServerDelete' },
        getBefore, Server.del);

    // Factory-reset server
    http.put({
        path: '/servers/:server_uuid/factory-reset',
        name: 'ServerFactoryReset' },
        getBefore, Server.factoryReset);
}

exports.attachTo = attachTo;
<|endoftext|>


<commit_before>// Simple Set Clipboard System
// Author: Joseph Huckaby

var ZeroClipboard = {

	version: "1.0.4-TableTools2",
	clients: {}, // registered upload clients on page, indexed by id
	moviePath: '', // URL to movie
	nextId: 1, // ID of next movie

	$: function(thingy) {
		// simple DOM lookup utility function
		if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
		if (!thingy.addClass) {
			// extend element with a few useful methods
			thingy.hide = function() { this.style.display = 'none'; };
			thingy.show = function() { this.style.display = ''; };
			thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
			thingy.removeClass = function(name) {
				this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
			};
			thingy.hasClass = function(name) {
				return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
			}
		}
		return thingy;
	},

	setMoviePath: function(path) {
		// set path to ZeroClipboard.swf
		this.moviePath = path;
	},

	dispatch: function(id, eventName, args) {
		// receive event from flash movie, send to client
		var client = this.clients[id];
		if (client) {
			client.receiveEvent(eventName, args);
		}
	},

	register: function(id, client) {
		// register new client to receive events
		this.clients[id] = client;
	},

	getDOMObjectPosition: function(obj) {
		// get absolute coordinates for dom element
		var info = {
			left: 0,
			top: 0,
			width: obj.width ? obj.width : obj.offsetWidth,
			height: obj.height ? obj.height : obj.offsetHeight
		};

		if ( obj.style.width != "" )
			info.width = obj.style.width.replace("px","");

		if ( obj.style.height != "" )
			info.height = obj.style.height.replace("px","");

		while (obj) {
			info.left += obj.offsetLeft;
			info.top += obj.offsetTop;
			obj = obj.offsetParent;
		}

		return info;
	},

	Client: function(elem) {
		// constructor for new simple upload client
		this.handlers = {};

		// unique ID
		this.id = ZeroClipboard.nextId++;
		this.movieId = 'ZeroClipboardMovie_' + this.id;

		// register client with singleton to receive flash events
		ZeroClipboard.register(this.id, this);

		// create movie
		if (elem) this.glue(elem);
	}
};

ZeroClipboard.Client.prototype = {

	id: 0, // unique ID for us
	ready: false, // whether movie is ready to receive events or not
	movie: null, // reference to movie object
	clipText: '', // text to copy to clipboard
	fileName: '', // default file save name
	action: 'copy', // action to perform
	handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
	cssEffects: true, // enable CSS mouse effects on dom container
	handlers: null, // user event handlers
	sized: false,

	glue: function(elem, title) {
		// glue to DOM element
		// elem can be ID or actual DOM element object
		this.domElement = ZeroClipboard.$(elem);

		// float just above object, or zIndex 99 if dom element isn't set
		var zIndex = 99;
		if (this.domElement.style.zIndex) {
			zIndex = parseInt(this.domElement.style.zIndex) + 1;
		}

		// find X/Y position of domElement
		var box = ZeroClipboard.getDOMObjectPosition(this.domElement);

		// create floating DIV above element
		this.div = document.createElement('div');
		var style = this.div.style;
		style.position = 'absolute';
		style.left = (this.domElement.offsetLeft)+'px';
		//style.left = (this.domElement.offsetLeft+2)+'px';
		style.top = this.domElement.offsetTop+'px';
		style.width = (box.width) + 'px';
		//style.width = (box.width-4) + 'px';
		style.height = box.height + 'px';
		style.zIndex = zIndex;
		if ( typeof title != "undefined" && title != "" ) {
			this.div.title = title;
		}
		if ( box.width != 0 && box.height != 0 ) {
			this.sized = true;
		}

		// style.backgroundColor = '#f00'; // debug
		this.domElement.parentNode.appendChild(this.div);

		this.div.innerHTML = this.getHTML( box.width, box.height );
	},

	positionElement: function() {
		var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
		var style = this.div.style;

		style.position = 'absolute';
		style.left = (this.domElement.offsetLeft)+'px';
		style.top = this.domElement.offsetTop+'px';
		style.width = box.width + 'px';
		style.height = box.height + 'px';

		if ( box.width != 0 && box.height != 0 ) {
			this.sized = true;
		}

		var flash = this.div.childNodes[0];
		flash.width = box.width;
		flash.height = box.height;
	},

	getHTML: function(width, height) {
		// return HTML for movie
		var html = '';
		var flashvars = 'id=' + this.id +
			'&width=' + width +
			'&height=' + height;

		if (navigator.userAgent.match(/MSIE/)) {
			// IE gets an OBJECT tag
			var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
			html += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
		}
		else {
			// all other browsers get an EMBED tag
			html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
		}
		return html;
	},

	hide: function() {
		// temporarily hide floater offscreen
		if (this.div) {
			this.div.style.left = '-2000px';
		}
	},

	show: function() {
		// show ourselves after a call to hide()
		this.reposition();
	},

	destroy: function() {
		// destroy control and floater
		if (this.domElement && this.div) {
			this.hide();
			this.div.innerHTML = '';

			var body = document.getElementsByTagName('body')[0];
			try { body.removeChild( this.div ); } catch(e) {;}

			this.domElement = null;
			this.div = null;
		}
	},

	reposition: function(elem) {
		// reposition our floating div, optionally to new container
		// warning: container CANNOT change size, only position
		if (elem) {
			this.domElement = ZeroClipboard.$(elem);
			if (!this.domElement) this.hide();
		}

		if (this.domElement && this.div) {
			var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
			var style = this.div.style;
			style.left = '' + box.left + 'px';
			style.top = '' + box.top + 'px';
		}
	},

	clearText: function() {
		// clear the text to be copy / saved
		this.clipText = '';
		if (this.ready) this.movie.clearText();
	},

	appendText: function(newText) {
		// append text to that which is to be copied / saved
		this.clipText += newText;
		if (this.ready) { this.movie.appendText(newText) ;}
	},

	setText: function(newText) {
		// set text to be copied to be copied / saved
		this.clipText = newText;
		if (this.ready) { this.movie.setText(newText) ;}
	},

	setCharSet: function(charSet) {
		// set the character set (UTF16LE or UTF8)
		this.charSet = charSet;
		if (this.ready) { this.movie.setCharSet(charSet) ;}
	},

	setBomInc: function(bomInc) {
		// set if the BOM should be included or not
		this.incBom = bomInc;
		if (this.ready) { this.movie.setBomInc(bomInc) ;}
	},

	setFileName: function(newText) {
		// set the file name
		this.fileName = newText;
		if (this.ready) this.movie.setFileName(newText);
	},

	setAction: function(newText) {
		// set action (save or copy)
		this.action = newText;
		if (this.ready) this.movie.setAction(newText);
	},

	addEventListener: function(eventName, func) {
		// add user event listener for event
		// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
		eventName = eventName.toString().toLowerCase().replace(/^on/, '');
		if (!this.handlers[eventName]) this.handlers[eventName] = [];
		this.handlers[eventName].push(func);
	},

	setHandCursor: function(enabled) {
		// enable hand cursor (true), or default arrow cursor (false)
		this.handCursorEnabled = enabled;
		if (this.ready) this.movie.setHandCursor(enabled);
	},

	setCSSEffects: function(enabled) {
		// enable or disable CSS effects on DOM container
		this.cssEffects = !!enabled;
	},

	receiveEvent: function(eventName, args) {
		// receive event from flash
		eventName = eventName.toString().toLowerCase().replace(/^on/, '');

		// special behavior for certain events
		switch (eventName) {
			case 'load':
				// movie claims it is ready, but in IE this isn't always the case...
				// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
				this.movie = document.getElementById(this.movieId);
				if (!this.movie) {
					var self = this;
					setTimeout( function() { self.receiveEvent('load', null); }, 1 );
					return;
				}

				// firefox on pc needs a "kick" in order to set these in certain cases
				if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
					var self = this;
					setTimeout( function() { self.receiveEvent('load', null); }, 100 );
					this.ready = true;
					return;
				}

				this.ready = true;
				this.movie.clearText();
				this.movie.appendText( this.clipText );
				this.movie.setFileName( this.fileName );
				this.movie.setAction( this.action );
				this.movie.setCharSet( this.charSet );
				this.movie.setBomInc( this.incBom );
				this.movie.setHandCursor( this.handCursorEnabled );
				break;

			case 'mouseover':
				if (this.domElement && this.cssEffects) {
					//this.domElement.addClass('hover');
					if (this.recoverActive) this.domElement.addClass('active');
				}
				break;

			case 'mouseout':
				if (this.domElement && this.cssEffects) {
					this.recoverActive = false;
					if (this.domElement.hasClass('active')) {
						this.domElement.removeClass('active');
						this.recoverActive = true;
					}
					//this.domElement.removeClass('hover');
				}
				break;

			case 'mousedown':
				if (this.domElement && this.cssEffects) {
					this.domElement.addClass('active');
				}
				break;

			case 'mouseup':
				if (this.domElement && this.cssEffects) {
					this.domElement.removeClass('active');
					this.recoverActive = false;
				}
				break;
		} // switch eventName

		if (this.handlers[eventName]) {
			for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
				var func = this.handlers[eventName][idx];

				if (typeof(func) == 'function') {
					// actual function reference
					func(this, args);
				}
				else if ((typeof(func) == 'object') && (func.length == 2)) {
					// PHP style object + method, i.e. [myObject, 'myMethod']
					func[0][ func[1] ](this, args);
				}
				else if (typeof(func) == 'string') {
					// name of function
					window[func](this, args);
				}
			} // foreach event handler defined
		} // user defined handler for event
	}

};
<commit_msg>Fix: When the height / width of a Flash movie is found to be 0, don't try to set the height / width, as IE will throw a JS error about the div's child nodes not existing<commit_after>// Simple Set Clipboard System
// Author: Joseph Huckaby

var ZeroClipboard = {

	version: "1.0.4-TableTools2",
	clients: {}, // registered upload clients on page, indexed by id
	moviePath: '', // URL to movie
	nextId: 1, // ID of next movie

	$: function(thingy) {
		// simple DOM lookup utility function
		if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
		if (!thingy.addClass) {
			// extend element with a few useful methods
			thingy.hide = function() { this.style.display = 'none'; };
			thingy.show = function() { this.style.display = ''; };
			thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
			thingy.removeClass = function(name) {
				this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
			};
			thingy.hasClass = function(name) {
				return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
			}
		}
		return thingy;
	},

	setMoviePath: function(path) {
		// set path to ZeroClipboard.swf
		this.moviePath = path;
	},

	dispatch: function(id, eventName, args) {
		// receive event from flash movie, send to client
		var client = this.clients[id];
		if (client) {
			client.receiveEvent(eventName, args);
		}
	},

	register: function(id, client) {
		// register new client to receive events
		this.clients[id] = client;
	},

	getDOMObjectPosition: function(obj) {
		// get absolute coordinates for dom element
		var info = {
			left: 0,
			top: 0,
			width: obj.width ? obj.width : obj.offsetWidth,
			height: obj.height ? obj.height : obj.offsetHeight
		};

		if ( obj.style.width != "" )
			info.width = obj.style.width.replace("px","");

		if ( obj.style.height != "" )
			info.height = obj.style.height.replace("px","");

		while (obj) {
			info.left += obj.offsetLeft;
			info.top += obj.offsetTop;
			obj = obj.offsetParent;
		}

		return info;
	},

	Client: function(elem) {
		// constructor for new simple upload client
		this.handlers = {};

		// unique ID
		this.id = ZeroClipboard.nextId++;
		this.movieId = 'ZeroClipboardMovie_' + this.id;

		// register client with singleton to receive flash events
		ZeroClipboard.register(this.id, this);

		// create movie
		if (elem) this.glue(elem);
	}
};

ZeroClipboard.Client.prototype = {

	id: 0, // unique ID for us
	ready: false, // whether movie is ready to receive events or not
	movie: null, // reference to movie object
	clipText: '', // text to copy to clipboard
	fileName: '', // default file save name
	action: 'copy', // action to perform
	handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
	cssEffects: true, // enable CSS mouse effects on dom container
	handlers: null, // user event handlers
	sized: false,

	glue: function(elem, title) {
		// glue to DOM element
		// elem can be ID or actual DOM element object
		this.domElement = ZeroClipboard.$(elem);

		// float just above object, or zIndex 99 if dom element isn't set
		var zIndex = 99;
		if (this.domElement.style.zIndex) {
			zIndex = parseInt(this.domElement.style.zIndex) + 1;
		}

		// find X/Y position of domElement
		var box = ZeroClipboard.getDOMObjectPosition(this.domElement);

		// create floating DIV above element
		this.div = document.createElement('div');
		var style = this.div.style;
		style.position = 'absolute';
		style.left = (this.domElement.offsetLeft)+'px';
		//style.left = (this.domElement.offsetLeft+2)+'px';
		style.top = this.domElement.offsetTop+'px';
		style.width = (box.width) + 'px';
		//style.width = (box.width-4) + 'px';
		style.height = box.height + 'px';
		style.zIndex = zIndex;
		if ( typeof title != "undefined" && title != "" ) {
			this.div.title = title;
		}
		if ( box.width != 0 && box.height != 0 ) {
			this.sized = true;
		}

		// style.backgroundColor = '#f00'; // debug
		this.domElement.parentNode.appendChild(this.div);

		this.div.innerHTML = this.getHTML( box.width, box.height );
	},

	positionElement: function() {
		var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
		var style = this.div.style;

		style.position = 'absolute';
		style.left = (this.domElement.offsetLeft)+'px';
		style.top = this.domElement.offsetTop+'px';
		style.width = box.width + 'px';
		style.height = box.height + 'px';

		if ( box.width != 0 && box.height != 0 ) {
			this.sized = true;
		} else {
			return;
		}

		var flash = this.div.childNodes[0];
		flash.width = box.width;
		flash.height = box.height;
	},

	getHTML: function(width, height) {
		// return HTML for movie
		var html = '';
		var flashvars = 'id=' + this.id +
			'&width=' + width +
			'&height=' + height;

		if (navigator.userAgent.match(/MSIE/)) {
			// IE gets an OBJECT tag
			var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
			html += '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
		}
		else {
			// all other browsers get an EMBED tag
			html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
		}
		return html;
	},

	hide: function() {
		// temporarily hide floater offscreen
		if (this.div) {
			this.div.style.left = '-2000px';
		}
	},

	show: function() {
		// show ourselves after a call to hide()
		this.reposition();
	},

	destroy: function() {
		// destroy control and floater
		if (this.domElement && this.div) {
			this.hide();
			this.div.innerHTML = '';

			var body = document.getElementsByTagName('body')[0];
			try { body.removeChild( this.div ); } catch(e) {;}

			this.domElement = null;
			this.div = null;
		}
	},

	reposition: function(elem) {
		// reposition our floating div, optionally to new container
		// warning: container CANNOT change size, only position
		if (elem) {
			this.domElement = ZeroClipboard.$(elem);
			if (!this.domElement) this.hide();
		}

		if (this.domElement && this.div) {
			var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
			var style = this.div.style;
			style.left = '' + box.left + 'px';
			style.top = '' + box.top + 'px';
		}
	},

	clearText: function() {
		// clear the text to be copy / saved
		this.clipText = '';
		if (this.ready) this.movie.clearText();
	},

	appendText: function(newText) {
		// append text to that which is to be copied / saved
		this.clipText += newText;
		if (this.ready) { this.movie.appendText(newText) ;}
	},

	setText: function(newText) {
		// set text to be copied to be copied / saved
		this.clipText = newText;
		if (this.ready) { this.movie.setText(newText) ;}
	},

	setCharSet: function(charSet) {
		// set the character set (UTF16LE or UTF8)
		this.charSet = charSet;
		if (this.ready) { this.movie.setCharSet(charSet) ;}
	},

	setBomInc: function(bomInc) {
		// set if the BOM should be included or not
		this.incBom = bomInc;
		if (this.ready) { this.movie.setBomInc(bomInc) ;}
	},

	setFileName: function(newText) {
		// set the file name
		this.fileName = newText;
		if (this.ready) this.movie.setFileName(newText);
	},

	setAction: function(newText) {
		// set action (save or copy)
		this.action = newText;
		if (this.ready) this.movie.setAction(newText);
	},

	addEventListener: function(eventName, func) {
		// add user event listener for event
		// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
		eventName = eventName.toString().toLowerCase().replace(/^on/, '');
		if (!this.handlers[eventName]) this.handlers[eventName] = [];
		this.handlers[eventName].push(func);
	},

	setHandCursor: function(enabled) {
		// enable hand cursor (true), or default arrow cursor (false)
		this.handCursorEnabled = enabled;
		if (this.ready) this.movie.setHandCursor(enabled);
	},

	setCSSEffects: function(enabled) {
		// enable or disable CSS effects on DOM container
		this.cssEffects = !!enabled;
	},

	receiveEvent: function(eventName, args) {
		// receive event from flash
		eventName = eventName.toString().toLowerCase().replace(/^on/, '');

		// special behavior for certain events
		switch (eventName) {
			case 'load':
				// movie claims it is ready, but in IE this isn't always the case...
				// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
				this.movie = document.getElementById(this.movieId);
				if (!this.movie) {
					var self = this;
					setTimeout( function() { self.receiveEvent('load', null); }, 1 );
					return;
				}

				// firefox on pc needs a "kick" in order to set these in certain cases
				if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
					var self = this;
					setTimeout( function() { self.receiveEvent('load', null); }, 100 );
					this.ready = true;
					return;
				}

				this.ready = true;
				this.movie.clearText();
				this.movie.appendText( this.clipText );
				this.movie.setFileName( this.fileName );
				this.movie.setAction( this.action );
				this.movie.setCharSet( this.charSet );
				this.movie.setBomInc( this.incBom );
				this.movie.setHandCursor( this.handCursorEnabled );
				break;

			case 'mouseover':
				if (this.domElement && this.cssEffects) {
					//this.domElement.addClass('hover');
					if (this.recoverActive) this.domElement.addClass('active');
				}
				break;

			case 'mouseout':
				if (this.domElement && this.cssEffects) {
					this.recoverActive = false;
					if (this.domElement.hasClass('active')) {
						this.domElement.removeClass('active');
						this.recoverActive = true;
					}
					//this.domElement.removeClass('hover');
				}
				break;

			case 'mousedown':
				if (this.domElement && this.cssEffects) {
					this.domElement.addClass('active');
				}
				break;

			case 'mouseup':
				if (this.domElement && this.cssEffects) {
					this.domElement.removeClass('active');
					this.recoverActive = false;
				}
				break;
		} // switch eventName

		if (this.handlers[eventName]) {
			for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
				var func = this.handlers[eventName][idx];

				if (typeof(func) == 'function') {
					// actual function reference
					func(this, args);
				}
				else if ((typeof(func) == 'object') && (func.length == 2)) {
					// PHP style object + method, i.e. [myObject, 'myMethod']
					func[0][ func[1] ](this, args);
				}
				else if (typeof(func) == 'string') {
					// name of function
					window[func](this, args);
				}
			} // foreach event handler defined
		} // user defined handler for event
	}

};
<|endoftext|>