<commit_before>/*global angular, io*/
angular.module('baboon.services', [])
    .factory('msgBox', function () {
        var pub = {},
            modal = {
                opts: {
                    backdropClick: false,
                    backdropFade: true,
                    dialogFade: true
                }
            };

        /**
         * Closes the modal window and clears the error message/action.
         */
        modal.close = function () {
            modal.shouldBeOpen = false;
            modal.message = '';
            modal.type = '';
            modal.action = null;
        };

        /**
         * Opens the modal window.
         *
         * @param {string} message The message to show.
         * @param {string=} type The message type.
         * @param {function=} callback The callback action when click the ok button in the modal window.
         */
        modal.show = function (message, type, callback) {
            modal.shouldBeOpen = true;
            modal.message = message;
            modal.type = type || 'Error';
            modal.action = callback;
        };

        /**
         * Executes the action and closes the modal window
         */
        modal.ok = function () {
            if (typeof modal.action === 'function') {
                modal.action.call();
            }

            modal.close();
        };

        pub.modal = modal;

        return pub;
    })
    .factory('socket', ['$rootScope', '$window', '$location', 'msgBox', function ($rootScope, $window, $location, msgBox) {
        var protocol = $window.location.protocol;
        var hostname = $window.location.hostname;
        var port = $window.location.port;
        var transports = ['websocket', 'xhr-polling', 'jsonp-polling'];

        if (protocol === 'https') {
            protocol = 'wss';
        }
        else {
            protocol = 'ws';
        }

        // karma fix
        if (port > 9870 && port < 9900 && hostname === 'localhost') {
            transports = ['xhr-polling', 'jsonp-polling'];
        }

        var host = protocol + '://' + hostname + ':' + port;
        var socket = io.connect(host, {'connect timeout': 4000, 'transports': transports});

        socket.on('error', function (err) {
            console.error('Unable to connect Socket.IO', err);

            $rootScope.$apply(function () {
                msgBox.modal.show('Server error!', 'Error');
            });
        });

        socket.on('disconnect', function () {
            console.error('Lost connection to Socket.IO');

            $rootScope.$apply(function () {
                msgBox.modal.show('Lost connection to server!', 'Warning');
            });
        });

        socket.on('connect', function () {
            console.log('socket.io connected with: ' + socket.socket.transport.name);
        });

        socket.on('connect_error', function (err) {
            console.error('connect_error: ', err);
        });

        socket.on('connect_timeout', function () {
            console.error('connect_timeout...');
        });

        socket.on('reconnect', function (transport) {
            console.log('socket.io reconnect with: ' + transport);

            $rootScope.$apply(function () {
                msgBox.modal.close();
            });
        });

        socket.on('reconnecting', function () {
            var reconnectionAttempts = arguments[1] || 0;
            console.log('Try to reconnect with: ' + socket.socket.transport.name + ', attempt: ' + reconnectionAttempts);

            $rootScope.$apply(function () {
                if (reconnectionAttempts === 1) {
                    msgBox.modal.message += ' Trying to reconnect. Attempt: ' + reconnectionAttempts;
                } else {
                    msgBox.modal.message = msgBox.modal.message.replace((reconnectionAttempts - 1).toString(), reconnectionAttempts);
                }
            });
        });

        socket.on('reconnect_error', function (err) {
            console.error('socket.io reconnect_error: ', err);
        });

        socket.on('reconnect_failed', function () {
            console.error('socket.io reconnect_failed');
        });

        socket.on('site_reload', function () {
            console.warn('Site Reload triggered by Server');

            $rootScope.$apply(function () {
                msgBox.modal.show('Session is expired! Please log in.', 'Warning', function () {
                    window.location.assign('/login');
                });
            });
        });

        return {
            on: function (eventName, callback) {
                socket.on(eventName, function () {
                    var args = arguments;
                    $rootScope.$apply(function () {
                        callback.apply(socket, args);
                    });
                });
            },
            emit: function (eventName, data, callback) {
                socket.emit(eventName, data, function () {
                    var args = arguments;
                    $rootScope.$apply(function () {
                        if (callback) {
                            callback.apply(socket, args);
                        }
                    });
                });
            }
        };
    }])
    .factory('cache', function () {
        return {};
    })
    .factory('lxPager', function () {
        return function (model) {
            var pub = {};

            pub.currentPage = 1;
            pub.count = 0;
            pub.pageSize = 5;
            pub.pageSizes = [1, 2, 3, 4, 5, 10];

            pub.skip = function () {
                return (pub.currentPage - 1) * pub.pageSize;
            };

            pub.numberOfPages = function () {
                if (pub.pageSize < 1) {
                    pub.pageSize = 1;
                }

                return Math.ceil(pub.count / pub.pageSize);
            };

            pub.getOptions = function () {
//                var params = model.params || {};

                return {
                    limit: pub.pageSize,
                    skip: pub.skip()
//                    fields: params.fields,
//                    sortBy: params.sortBy,
//                    sort: params.sort
                };
            };

            pub.getAll = function () {
                model.service.getAllWithCount({
                    params: (model.params || {}).filter || {},
                    options: pub.getOptions()
                }, function (result) {
                    if (result.count) {
                        pub.count = result.count;
                    }

                    model.callback(result);
                });
            };

            pub.nextPage = function () {
                var currentPage = pub.currentPage;
                var count = currentPage * pub.pageSize;

                if (count < pub.count) {
                    pub.currentPage = ++currentPage;
//                    pub.getAll();
                }
            };

            pub.previousPage = function () {
                var currentPage = pub.currentPage;

                if (currentPage !== 1) {
                    pub.currentPage = --currentPage;
//                    pub.getAll();
                }
            };

            pub.firstPage = function () {
                pub.currentPage = 1;
//                pub.getAll();
            };

            pub.lastPage = function () {
                pub.currentPage = pub.numberOfPages();
            };

            return pub;
        };
    })
    .factory('lxForm', ['cache', function (cache) {
        return function (modelName, key) {
            var pub = {},
                master = {};

            pub.model = {};

            /**
             * Resets the model to the master.
             *
             * @param {object} form The angularjs formcontroller.
             */
            pub.reset = function (form) {
                if (form) {
                    // clear form errors
                    form.errors = {};
                }

                // reset model
                pub.model = angular.copy(master);

                if (key) {
                    // reset model in cache
                    if (pub.model[key]) {
                        cache[pub.model[key]] = pub.model;
                    } else {
                        cache[modelName] = pub.model;
                    }
                }
            };

            /**
             * Checks if the model has changes.
             *
             * @returns {boolean}
             */
            pub.isUnchanged = function () {
                return angular.equals(pub.model, master);
            };

            /**
             * Tries to load the model from cache.
             *
             * @param {string=} key The key of the model.
             * @returns {boolean}
             */
            pub.hasLoadedModelFromCache = function (key) {
                if (key && cache[key]) {
                    // load from cache
                    pub.model = cache[key];

                    if (cache[key + '_Master']) {
                        master = cache[key + '_Master'];
                    }

                    return true;
                } else if (!key) {
                    if (cache[modelName]) {
                        // load from cache
                        pub.model = cache[modelName];
                    } else {
                        // set cache
                        cache[modelName] = pub.model;
                    }

                    return true;
                }

                return false;
            };

            /**
             * Sets the model.
             *
             * @param {object} model The model.
             * @param {boolean} resetCache Specifies if the cache should be resettet.
             */
            pub.setModel = function (model, resetCache) {
                if (!pub.model[key] && resetCache) {
                    // no key -> create, delete model from cache
                    delete cache[modelName];
                }

                // set model
                pub.model = model;
                master = angular.copy(model);

                if (resetCache) {
                    // reset cache
                    delete cache[model[key]];
                    delete cache[model[key] + '_Master'];
                } else {
                    // set cache
                    cache[model[key]] = pub.model;
                    cache[model[key] + '_Master'] = master;
                }
            };

            /**
             * Add server validation to form.
             *
             * @param {object} form The angularjs form controller.
             * @param errors
             */
            pub.populateValidation = function (form, errors) {
                if (errors) {
                    // reset form errors
                    form.errors = {};

                    for (var i = 0; i < errors.length; i++) {
//                        form[errors[i].property].$invalid = true;
//                        form[errors[i].property].$dirty = true;
                        // set form errors
                        form.errors[errors[i].property] = errors[i].attribute + ' ' + errors[i].message;
                    }
                }
            };

            return pub;
        };
    }])
    .factory('inlineEdit', function () {
        return function () {
            var pub = {},
                master = {};

            pub.model = {};

            pub.isUnchanged = function () {
                return angular.equals(pub.model, master);
            };

            pub.reset = function (model, form) {
                if (form) {
                    form.errors = {};
                }

                angular.copy(master, model);
                pub.model = angular.copy(master);
            };

            pub.setModel = function (model) {
                pub.model = model;
                master = angular.copy(model);
            };

            pub.populateValidation = function (form, errors) {
                if (errors) {
                    form.errors = {};

                    for (var i = 0; i < errors.length; i++) {
                        form.errors[errors[i].property] = errors[i].attribute + ' ' + errors[i].message;
                    }
                }
            };

            return pub;
        };
    })
    .factory('session', ['socket', function (socket) {
        var pub = {};

        console.log('session started');

        pub.getAll = function (callback) {
            socket.emit('session:getAll', {}, callback);
        };

        pub.setData = function (data, callback) {
            socket.emit('session:setData', data, callback);
        };

        pub.getData = function (key, callback) {
            socket.emit('session:getData', key, callback);
        };

        pub.setActivity = function () {
            console.log('session_activity');
            socket.emit('session_activity');
        };

        return pub;
    }]);
<commit_msg>feat(socket): show correct error message when server session is expired.<commit_after>/*global angular, io*/
angular.module('baboon.services', [])
    .factory('msgBox', function () {
        var pub = {},
            modal = {
                opts: {
                    backdropClick: false,
                    backdropFade: true,
                    dialogFade: true
                }
            };

        /**
         * Closes the modal window and clears the error message/action.
         */
        modal.close = function () {
            modal.shouldBeOpen = false;
            modal.message = '';
            modal.type = '';
            modal.action = null;
        };

        /**
         * Opens the modal window.
         *
         * @param {string} message The message to show.
         * @param {string=} type The message type.
         * @param {function=} callback The callback action when click the ok button in the modal window.
         */
        modal.show = function (message, type, callback) {
            modal.shouldBeOpen = true;
            modal.message = message;
            modal.type = type || 'Error';
            modal.action = callback;
        };

        /**
         * Executes the action and closes the modal window
         */
        modal.ok = function () {
            if (typeof modal.action === 'function') {
                modal.action.call();
            }

            modal.close();
        };

        pub.modal = modal;

        return pub;
    })
    .factory('socket', ['$rootScope', '$window', '$location', 'msgBox', function ($rootScope, $window, $location, msgBox) {
        var protocol = $window.location.protocol;
        var hostname = $window.location.hostname;
        var port = $window.location.port;
        var transports = ['websocket', 'xhr-polling', 'jsonp-polling'];

        if (protocol === 'https') {
            protocol = 'wss';
        }
        else {
            protocol = 'ws';
        }

        // karma fix
        if (port > 9870 && port < 9900 && hostname === 'localhost') {
            transports = ['xhr-polling', 'jsonp-polling'];
        }

        var host = protocol + '://' + hostname + ':' + port;
        var socket = io.connect(host, {'connect timeout': 4000, 'transports': transports});

        socket.on('error', function (err) {
            console.error('Unable to connect Socket.IO: ', err);

            if (err === 'handshake unauthorized') {
                $rootScope.$apply(function () {
                    msgBox.modal.show('Session is expired! Please log in.', 'Warning', function () {
                        window.location.assign('/login');
                    });
                });
            } else {
                $rootScope.$apply(function () {
                    msgBox.modal.show('Server error! ' + err, 'Error');
                });
            }
        });

        socket.on('disconnect', function () {
            console.error('Lost connection to Socket.IO');

            $rootScope.$apply(function () {
                msgBox.modal.show('Lost connection to server!', 'Warning');
            });
        });

        socket.on('connect', function () {
            console.log('socket.io connected with: ' + socket.socket.transport.name);
        });

        socket.on('connect_error', function (err) {
            console.error('connect_error: ', err);
        });

        socket.on('connect_timeout', function () {
            console.error('connect_timeout...');
        });

        socket.on('reconnect', function (transport) {
            console.log('socket.io reconnect with: ' + transport);

            $rootScope.$apply(function () {
                msgBox.modal.close();
            });
        });

        socket.on('reconnecting', function () {
            var reconnectionAttempts = arguments[1] || 0;
            console.log('Try to reconnect with: ' + socket.socket.transport.name + ', attempt: ' + reconnectionAttempts);

            $rootScope.$apply(function () {
                if (reconnectionAttempts === 1) {
                    msgBox.modal.message += ' Trying to reconnect. Attempt: ' + reconnectionAttempts;
                } else {
                    msgBox.modal.message = msgBox.modal.message.replace((reconnectionAttempts - 1).toString(), reconnectionAttempts);
                }
            });
        });

        socket.on('reconnect_error', function (err) {
            console.error('socket.io reconnect_error: ', err);
        });

        socket.on('reconnect_failed', function () {
            console.error('socket.io reconnect_failed');
        });

        socket.on('site_reload', function () {
            console.warn('Site Reload triggered by Server');

            $rootScope.$apply(function () {
                msgBox.modal.show('Session is expired! Please log in.', 'Warning', function () {
                    window.location.assign('/login');
                });
            });
        });

        return {
            on: function (eventName, callback) {
                socket.on(eventName, function () {
                    var args = arguments;
                    $rootScope.$apply(function () {
                        callback.apply(socket, args);
                    });
                });
            },
            emit: function (eventName, data, callback) {
                socket.emit(eventName, data, function () {
                    var args = arguments;
                    $rootScope.$apply(function () {
                        if (callback) {
                            callback.apply(socket, args);
                        }
                    });
                });
            }
        };
    }])
    .factory('cache', function () {
        return {};
    })
    .factory('lxPager', function () {
        return function (model) {
            var pub = {};

            pub.currentPage = 1;
            pub.count = 0;
            pub.pageSize = 5;
            pub.pageSizes = [1, 2, 3, 4, 5, 10];

            pub.skip = function () {
                return (pub.currentPage - 1) * pub.pageSize;
            };

            pub.numberOfPages = function () {
                if (pub.pageSize < 1) {
                    pub.pageSize = 1;
                }

                return Math.ceil(pub.count / pub.pageSize);
            };

            pub.getOptions = function () {
//                var params = model.params || {};

                return {
                    limit: pub.pageSize,
                    skip: pub.skip()
//                    fields: params.fields,
//                    sortBy: params.sortBy,
//                    sort: params.sort
                };
            };

            pub.getAll = function () {
                model.service.getAllWithCount({
                    params: (model.params || {}).filter || {},
                    options: pub.getOptions()
                }, function (result) {
                    if (result.count) {
                        pub.count = result.count;
                    }

                    model.callback(result);
                });
            };

            pub.nextPage = function () {
                var currentPage = pub.currentPage;
                var count = currentPage * pub.pageSize;

                if (count < pub.count) {
                    pub.currentPage = ++currentPage;
//                    pub.getAll();
                }
            };

            pub.previousPage = function () {
                var currentPage = pub.currentPage;

                if (currentPage !== 1) {
                    pub.currentPage = --currentPage;
//                    pub.getAll();
                }
            };

            pub.firstPage = function () {
                pub.currentPage = 1;
//                pub.getAll();
            };

            pub.lastPage = function () {
                pub.currentPage = pub.numberOfPages();
            };

            return pub;
        };
    })
    .factory('lxForm', ['cache', function (cache) {
        return function (modelName, key) {
            var pub = {},
                master = {};

            pub.model = {};

            /**
             * Resets the model to the master.
             *
             * @param {object} form The angularjs formcontroller.
             */
            pub.reset = function (form) {
                if (form) {
                    // clear form errors
                    form.errors = {};
                }

                // reset model
                pub.model = angular.copy(master);

                if (key) {
                    // reset model in cache
                    if (pub.model[key]) {
                        cache[pub.model[key]] = pub.model;
                    } else {
                        cache[modelName] = pub.model;
                    }
                }
            };

            /**
             * Checks if the model has changes.
             *
             * @returns {boolean}
             */
            pub.isUnchanged = function () {
                return angular.equals(pub.model, master);
            };

            /**
             * Tries to load the model from cache.
             *
             * @param {string=} key The key of the model.
             * @returns {boolean}
             */
            pub.hasLoadedModelFromCache = function (key) {
                if (key && cache[key]) {
                    // load from cache
                    pub.model = cache[key];

                    if (cache[key + '_Master']) {
                        master = cache[key + '_Master'];
                    }

                    return true;
                } else if (!key) {
                    if (cache[modelName]) {
                        // load from cache
                        pub.model = cache[modelName];
                    } else {
                        // set cache
                        cache[modelName] = pub.model;
                    }

                    return true;
                }

                return false;
            };

            /**
             * Sets the model.
             *
             * @param {object} model The model.
             * @param {boolean} resetCache Specifies if the cache should be resettet.
             */
            pub.setModel = function (model, resetCache) {
                if (!pub.model[key] && resetCache) {
                    // no key -> create, delete model from cache
                    delete cache[modelName];
                }

                // set model
                pub.model = model;
                master = angular.copy(model);

                if (resetCache) {
                    // reset cache
                    delete cache[model[key]];
                    delete cache[model[key] + '_Master'];
                } else {
                    // set cache
                    cache[model[key]] = pub.model;
                    cache[model[key] + '_Master'] = master;
                }
            };

            /**
             * Add server validation to form.
             *
             * @param {object} form The angularjs form controller.
             * @param errors
             */
            pub.populateValidation = function (form, errors) {
                if (errors) {
                    // reset form errors
                    form.errors = {};

                    for (var i = 0; i < errors.length; i++) {
//                        form[errors[i].property].$invalid = true;
//                        form[errors[i].property].$dirty = true;
                        // set form errors
                        form.errors[errors[i].property] = errors[i].attribute + ' ' + errors[i].message;
                    }
                }
            };

            return pub;
        };
    }])
    .factory('inlineEdit', function () {
        return function () {
            var pub = {},
                master = {};

            pub.model = {};

            pub.isUnchanged = function () {
                return angular.equals(pub.model, master);
            };

            pub.reset = function (model, form) {
                if (form) {
                    form.errors = {};
                }

                angular.copy(master, model);
                pub.model = angular.copy(master);
            };

            pub.setModel = function (model) {
                pub.model = model;
                master = angular.copy(model);
            };

            pub.populateValidation = function (form, errors) {
                if (errors) {
                    form.errors = {};

                    for (var i = 0; i < errors.length; i++) {
                        form.errors[errors[i].property] = errors[i].attribute + ' ' + errors[i].message;
                    }
                }
            };

            return pub;
        };
    })
    .factory('session', ['socket', function (socket) {
        var pub = {};

        console.log('session started');

        pub.getAll = function (callback) {
            socket.emit('session:getAll', {}, callback);
        };

        pub.setData = function (data, callback) {
            socket.emit('session:setData', data, callback);
        };

        pub.getData = function (key, callback) {
            socket.emit('session:getData', key, callback);
        };

        pub.setActivity = function () {
            console.log('session_activity');
            socket.emit('session_activity');
        };

        return pub;
    }]);
<|endoftext|>


<commit_before>var map, service, infowindow,reference,workid,marker_list = new google.maps.MVCArray(), latlngSW = [
        20.425277, 122.933611 ], latlngNE = [ 45.557777, 153.986388 ], thisBounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(latlngSW[0], latlngSW[1]),
        new google.maps.LatLng(latlngNE[0], latlngNE[1])), thisCenter = new google.maps.LatLng(
        35.698683, 139.774219);

function initialize() {
    if((/^\d+$/).test(location.search.substr(1))){
      workid = location.search.substr(1);
    }else{
      workid = null;
    }
    map = new google.maps.Map(document.getElementById('map'), {
        center : thisCenter,
        zoom : 15
    });
    service = new google.maps.places.PlacesService(map);
    map.fitBounds(thisBounds);
    document.getElementById('search-button').onclick = searchStr;
    document.getElementById('map').className = 'show';
}

function searchStr() {
    var request = {
        bounds : new google.maps.LatLngBounds(new google.maps.LatLng(
                latlngSW[0], latlngSW[1]), new google.maps.LatLng(latlngNE[0],
                latlngNE[1])),
        query : document.getElementById('str').value
    };
    document.getElementById('search-result').innerHTML = '';
    marker_list.forEach(function(marker, idx) {
        marker.setMap(null);
    });
    infowindow = new google.maps.InfoWindow();
    /* console.log('callback:do -> ' + request.query); */
    service.textSearch(request, callback);
}
function callback(results, status) {
    var thisLatlngNE = new Array(2), thisLatlngSW = new Array(
            2);
    /* console.log('callback:get -> ' + results.length); */
    if (status == google.maps.places.PlacesServiceStatus.OK) {
        results.sort(function(a,b){
            if (a.rating != undefined && b.rating == undefined){
              return -1;
            }
            if (a.rating == undefined && b.rating != undefined){
              return 1;
            }
          // a は b と等しいはず
          return 0;
        });
        for (var i = 0; i < results.length; i++) {
            var element = document.createElement('div');
            element.className='search-result-item input-group';
            element.id='detail-' + i;
            var lat = undefined, lng = undefined;
            createMarker(results[i],i);
            lat = results[i].geometry.location.d;
            lng = results[i].geometry.location.e;
            if (thisLatlngSW[0] > lat || i == 0) {
                thisLatlngSW[0] = lat;
            }
            if (thisLatlngNE[0] < lat || i == 0) {
                thisLatlngNE[0] = lat;
            }
            if (thisLatlngSW[1] > lng || i == 0) {
                thisLatlngSW[1] = lng;
            }
            if (thisLatlngNE[1] < lat || i == 0) {
                thisLatlngNE[1] = lng;
            }
            thisBounds = new google.maps.LatLngBounds(new google.maps.LatLng(
                    thisLatlngSW[0], thisLatlngSW[1]), new google.maps.LatLng(
                    thisLatlngNE[0], thisLatlngNE[1]));
            console.log(thisLatlngSW[0] + ' : ' + thisLatlngSW[1] + ' : '
                    + thisLatlngNE[0] + ' : ' + thisLatlngNE[1]);
            element.innerHTML = '
' + results[i].name + '
'
                    +'<form action="confirmplaceadd" method="post">'
                    + '名前<input class="form-control" type="text" name="name" value="'
                    + results[i].name
                    + '">'
                    + '<button type="button" class="btn btn-default btn-xs" data-toggle="collapse" data-target="#detailinfo-'
                    + i
                    + '" id="detail-button-'
                    + i
                    + '" data-detail-number="'
                    + i
                    +'">詳細</button>'
                    + '
'
                    + '住所：<input class="form-control" type="text" name="address" value="'
                    + results[i].formatted_address.replace('日本, ', '')
                    + '">'
                    + '緯度：<input class="form-control" type="number" step="0.000001" name="lat" value="'
                    + (Math.ceil(lat*1000000))/1000000
                    + '">'
                    + '経度：<input class="form-control" type="number" step="0.000001" name="lng" value="'
                    + (Math.ceil(lng*1000000))/1000000
                    + '">'
                    + 'Google Place Reference：<input class="form-control" type="text" name="googleid" value="'
                    + results[i].reference
                    + '">'
                    + 'Google Place(Google+)のURL(url1)：<input class="form-control" type="url" name="url1" value="" id="detail-url-'
                    + i + '">'
                    + '<input type="hidden" name="urlname1" value="' + results[i].name + ' - 基本情報 - Google+">'
                    + (workid == null ? '' : ('<input type="hidden" name="workid" value="' + workid + '">' ))
                    + '<input class="btn btn-primary" type="submit" value="送信">'
                    + '
' + '</form>';
            document.getElementById('search-result').appendChild(element);
            document.getElementById('detail-button-' + i ).onclick = (function(reference,i){
                return function(){
                    moreDetail(reference,i);
                };
            })(results[i].reference,i);
        }
        map.fitBounds(thisBounds);
        if (map.zoom > 17) {
            map.setZoom(17);
        }
    } else {
        /* console.log('error : ' + status); */
    }
}
function createMarker(place,i) {
    var marker = new google.maps.Marker({
        map : map,
        position : place.geometry.location
    });
    marker_list.push(marker);

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent('' + place.name + '');
        infowindow.open(map, this);
    });
}
function moreDetail(reference,i) {
    /* console.log('click'); */
    var request = {
        reference : reference
    };
    service.getDetails(request,function(place,status){
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            document.getElementById('detail-url-' + i ).value = place.url;
          }
    });
}

google.maps.event.addDomListener(window, 'load', initialize);<commit_msg>Debug placeadd.js<commit_after>var map, service, infowindow,reference,workid,marker_list = new google.maps.MVCArray(), latlngSW = [
        20.425277, 122.933611 ], latlngNE = [ 45.557777, 153.986388 ], thisBounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(latlngSW[0], latlngSW[1]),
        new google.maps.LatLng(latlngNE[0], latlngNE[1])), thisCenter = new google.maps.LatLng(
        35.698683, 139.774219);

function initialize() {
    if((/^\d+$/).test(location.search.substr(1))){
      workid = location.search.substr(1);
    }else{
      workid = null;
    }
    map = new google.maps.Map(document.getElementById('map'), {
        center : thisCenter,
        zoom : 15
    });
    service = new google.maps.places.PlacesService(map);
    map.fitBounds(thisBounds);
    document.getElementById('search-button').onclick = searchStr;
    document.getElementById('map').className = 'show';
}

function searchStr() {
    var request = {
        bounds : new google.maps.LatLngBounds(new google.maps.LatLng(
                latlngSW[0], latlngSW[1]), new google.maps.LatLng(latlngNE[0],
                latlngNE[1])),
        query : document.getElementById('str').value
    };
    document.getElementById('search-result').innerHTML = '';
    marker_list.forEach(function(marker, idx) {
        marker.setMap(null);
    });
    infowindow = new google.maps.InfoWindow();
    /* console.log('callback:do -> ' + request.query); */
    service.textSearch(request, callback);
}
function callback(results, status) {
    var thisLatlngNE = new Array(2), thisLatlngSW = new Array(
            2);
    /* console.log('callback:get -> ' + results.length); */
    if (status == google.maps.places.PlacesServiceStatus.OK) {
        results.sort(function(a,b){
            if (a.rating != undefined && b.rating == undefined){
              return -1;
            }
            if (a.rating == undefined && b.rating != undefined){
              return 1;
            }
          // a は b と等しいはず
          return 0;
        });
        for (var i = 0; i < results.length; i++) {
            var element = document.createElement('div');
            element.className='search-result-item input-group';
            element.id='detail-' + i;
            var lat = undefined, lng = undefined;
            createMarker(results[i],i);
            lat = results[i].geometry.location.d;
            lng = results[i].geometry.location.e;
            if (thisLatlngSW[0] > lat || i == 0) {
                thisLatlngSW[0] = lat;
            }
            if (thisLatlngNE[0] < lat || i == 0) {
                thisLatlngNE[0] = lat;
            }
            if (thisLatlngSW[1] > lng || i == 0) {
                thisLatlngSW[1] = lng;
            }
            if (thisLatlngNE[1] < lat || i == 0) {
                thisLatlngNE[1] = lng;
            }
            thisBounds = new google.maps.LatLngBounds(new google.maps.LatLng(
                    thisLatlngSW[0], thisLatlngSW[1]), new google.maps.LatLng(
                    thisLatlngNE[0], thisLatlngNE[1]));
            console.log(thisLatlngSW[0] + ' : ' + thisLatlngSW[1] + ' : '
                    + thisLatlngNE[0] + ' : ' + thisLatlngNE[1]);
            element.innerHTML = '
' + results[i].name + '
'
                    +'<form action="confirmplaceadd" method="post">'
                    + '名前<input class="form-control" type="text" name="name" value="'
                    + results[i].name
                    + '">'
                    + '<button type="button" class="btn btn-default btn-xs" data-toggle="collapse" data-target="#detailinfo-'
                    + i
                    + '" id="detail-button-'
                    + i
                    + '" data-detail-number="'
                    + i
                    +'">詳細</button>'
                    + '
'
                    + '住所：<input class="form-control" type="text" name="address" value="'
                    + results[i].formatted_address.replace('日本, ', '')
                    + '">'
/*                    + '緯度：<input class="form-control" type="number" step="0.000001" name="lat" value="'
                    + (Math.ceil(lat*1000000))/1000000
                    + '">'
                    + '経度：<input class="form-control" type="number" step="0.000001" name="lng" value="'
                    + (Math.ceil(lng*1000000))/1000000
                    + '">'*/
                   + '緯度：<input class="form-control" type="text" name="lat" value="'
                    + (Math.ceil(lat*1000000))/1000000
                    + '">'
                    + '経度：<input class="form-control" type="text" name="lng" value="'
                    + (Math.ceil(lng*1000000))/1000000
                    + '">'
                    + 'Google Place Reference：<input class="form-control" type="text" name="googleid" value="'
                    + results[i].reference
                    + '">'
                    + 'Google Place(Google+)のURL(url1)：<input class="form-control" type="url" name="url1" value="" id="detail-url-'
                    + i + '">'
                    + '<input type="hidden" name="urlname1" value="' + results[i].name + ' - 基本情報 - Google+">'
                    + (workid == null ? '' : ('<input type="hidden" name="workid" value="' + workid + '">' ))
                    + '<input class="btn btn-primary" type="submit" value="送信">'
                    + '
' + '</form>';
            document.getElementById('search-result').appendChild(element);
            document.getElementById('detail-button-' + i ).onclick = (function(reference,i){
                return function(){
                    moreDetail(reference,i);
                };
            })(results[i].reference,i);
        }
        map.fitBounds(thisBounds);
        if (map.zoom > 17) {
            map.setZoom(17);
        }
    } else {
        /* console.log('error : ' + status); */
    }
}
function createMarker(place,i) {
    var marker = new google.maps.Marker({
        map : map,
        position : place.geometry.location
    });
    marker_list.push(marker);

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent('' + place.name + '');
        infowindow.open(map, this);
    });
}
function moreDetail(reference,i) {
    /* console.log('click'); */
    var request = {
        reference : reference
    };
    service.getDetails(request,function(place,status){
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            document.getElementById('detail-url-' + i ).value = place.url;
          }
    });
}

google.maps.event.addDomListener(window, 'load', initialize);
<|endoftext|>


<commit_before>/**
 * Talisman clustering/k-means
 * ============================
 *
 * Function related to k-means clustering.
 *
 * [Reference]: https://en.wikipedia.org/wiki/K-means_clustering
 */
import euclidean from '../metrics/euclidean';
import {mean} from '../helpers/vectors';
import sample from 'lodash/sample';

/**
 * Helpers.
 */
function compareCentroids(a, b) {
  for (let i = 0, l = a.length; i < l; i++) {
    for (let j = 0, m = a[i].length; j < m; j++) {
      if (a[i][j] !== b[i][j])
        return false;
    }
  }

  return true;
}

/**
 * Function performing a k-means clustering on the given dataset.
 *
 * @param  {array}    dataset                 - An array of vectors of n
 *                                              dimensions.
 * @param  {number}   [k]                     - The number of clusters to
 *                                              produce.
 * @param  {object}   [options]               - Custom options.
 * @param  {function} [options.distance]      - The distance function to use.
 * @param  {number}   [options.maxIterations] - Max nb of iterations to perform.
 * @return {array}                            - An array of clusters.
 *
 * @throws {Error} Will throw if the given parameters are not valid.
 */
export default function kMeans(dataset, k = 8, options = {}) {
  const {
    distance = euclidean,
    maxIterations = 300
  } = options;

  if (!Array.isArray(dataset))
    throw Error('talisman/clustering/k-means: dataset should be an array of vectors.');

  if (typeof k !== 'number' || k <= 0)
    throw Error('talisman/clustering/k-means: k should be > 0.');

  if (typeof distance !== 'function')
    throw Error('talisman/clustering/k-means: the distance option should be a function.');

  if (typeof maxIterations !== 'number' || maxIterations <= 0)
    throw Error('talisman/clustering/k-means: the maxIterations option should be > 0.');

  // First we need to find random centroids to start
  let centroids = new Array(k);

  for (let i = 0; i < k; i++)
    centroids[i] = sample(dataset).slice();

  let iterations = 0,
      oldCentroids,
      clusters;

  // While we don't converge, or haven't performed the allowed iterations
  while (
    iterations < maxIterations &&
    (!oldCentroids || !compareCentroids(centroids, oldCentroids))
  ) {

    // Initializing the clusters
    clusters = new Array(k);

    for (let i = 0, l = clusters.length; i < l; i++)
      clusters[i] = [];

    // Iterating through the dataset's vectors
    for (let i = 0, l = dataset.length; i < l; i++) {
      const vector = dataset[i];

      // Finding the closest centroid
      let min = Infinity,
          minIndex = 0;

      for (let j = 0, m = centroids.length; j < m; j++) {
        const d = distance(vector, centroids[j]);

        if (d < min) {
          min = d;
          minIndex = j;
        }
      }

      // Pushing the vector in the correct cluster
      clusters[minIndex].push(vector);
    }

    // If any of the clusters is empty, we fill it with a random vector
    for (let i = 0, l = clusters.length; i < l; i++) {
      const cluster = clusters[i];

      if (cluster.length)
        continue;

      cluster.push(sample(dataset));
    }

    // We now find the new centroids
    oldCentroids = centroids;
    centroids = new Array(k);

    for (let i = 0, l = clusters.length; i < l; i++)
      centroids[i] = mean(clusters[i]);

    iterations++;
  }

  // Finally returning the clusters
  return clusters;
}
<commit_msg>Dropping useless line<commit_after>/**
 * Talisman clustering/k-means
 * ============================
 *
 * Function related to k-means clustering.
 *
 * [Reference]: https://en.wikipedia.org/wiki/K-means_clustering
 */
import euclidean from '../metrics/euclidean';
import {mean} from '../helpers/vectors';
import sample from 'lodash/sample';

/**
 * Helpers.
 */
function compareCentroids(a, b) {
  for (let i = 0, l = a.length; i < l; i++) {
    for (let j = 0, m = a[i].length; j < m; j++) {
      if (a[i][j] !== b[i][j])
        return false;
    }
  }

  return true;
}

/**
 * Function performing a k-means clustering on the given dataset.
 *
 * @param  {array}    dataset                 - An array of vectors of n
 *                                              dimensions.
 * @param  {number}   [k]                     - The number of clusters to
 *                                              produce.
 * @param  {object}   [options]               - Custom options.
 * @param  {function} [options.distance]      - The distance function to use.
 * @param  {number}   [options.maxIterations] - Max nb of iterations to perform.
 * @return {array}                            - An array of clusters.
 *
 * @throws {Error} Will throw if the given parameters are not valid.
 */
export default function kMeans(dataset, k = 8, options = {}) {
  const {
    distance = euclidean,
    maxIterations = 300
  } = options;

  if (!Array.isArray(dataset))
    throw Error('talisman/clustering/k-means: dataset should be an array of vectors.');

  if (typeof k !== 'number' || k <= 0)
    throw Error('talisman/clustering/k-means: k should be > 0.');

  if (typeof distance !== 'function')
    throw Error('talisman/clustering/k-means: the distance option should be a function.');

  if (typeof maxIterations !== 'number' || maxIterations <= 0)
    throw Error('talisman/clustering/k-means: the maxIterations option should be > 0.');

  // First we need to find random centroids to start
  let centroids = new Array(k);

  for (let i = 0; i < k; i++)
    centroids[i] = sample(dataset);

  let iterations = 0,
      oldCentroids,
      clusters;

  // While we don't converge, or haven't performed the allowed iterations
  while (
    iterations < maxIterations &&
    (!oldCentroids || !compareCentroids(centroids, oldCentroids))
  ) {

    // Initializing the clusters
    clusters = new Array(k);

    for (let i = 0, l = clusters.length; i < l; i++)
      clusters[i] = [];

    // Iterating through the dataset's vectors
    for (let i = 0, l = dataset.length; i < l; i++) {
      const vector = dataset[i];

      // Finding the closest centroid
      let min = Infinity,
          minIndex = 0;

      for (let j = 0, m = centroids.length; j < m; j++) {
        const d = distance(vector, centroids[j]);

        if (d < min) {
          min = d;
          minIndex = j;
        }
      }

      // Pushing the vector in the correct cluster
      clusters[minIndex].push(vector);
    }

    // If any of the clusters is empty, we fill it with a random vector
    for (let i = 0, l = clusters.length; i < l; i++) {
      const cluster = clusters[i];

      if (cluster.length)
        continue;

      cluster.push(sample(dataset));
    }

    // We now find the new centroids
    oldCentroids = centroids;
    centroids = new Array(k);

    for (let i = 0, l = clusters.length; i < l; i++)
      centroids[i] = mean(clusters[i]);

    iterations++;
  }

  // Finally returning the clusters
  return clusters;
}
<|endoftext|>


<commit_before>define([
  'underscore',
  'jquery',
  'backbone',
  'text!templates/plaque_editor.tpl',
  'collections/media',
  'collections/items',
  'models/game',
  'models/plaque',
  'models/event_package',
  'collections/events',
  'views/media_chooser',
  'views/event_package_editor',
  'vent',
  'storage',
],
function(
  _,
  $,
  Backbone,
  Template,
  MediaCollection,
  ItemsCollection,
  Game,
  Plaque,
  EventPackage,
  EventsCollection,
  MediaChooserView,
  EventPackageEditorView,
  vent,
  storage
)
{
  return Backbone.Marionette.CompositeView.extend(
  {
    template:_.template(Template),

    templateHelpers:function()
    {
      var self = this;
      return {
        is_new: self.model.isNew(),
        icon_thumbnail_url:  self.model.icon_thumbnail(),
        media_thumbnail_url: self.model.media_thumbnail(),
        option_selected: function(boolean_statement) { return boolean_statement ? "selected" : ""; },
        function_types: Plaque.function_types,
      };
    },

    ui:
    {
      "save":         ".save",
      "delete":       ".delete",
      "cancel":       ".cancel",
      "change_icon":  ".change-icon",
      "change_media": ".change-media",
      "edit_events":  ".edit-events",
      "name":         "#plaque-name",
      "description":  "#plaque-description",
      "continue_function": "#continue-function",
    },

    initialize: function(options)
    {
      var self = this;
      self.storePreviousAttributes();
      self.bindAssociations();
      self.on("popup:hide", self.onClickCancel);
    },

    onShow: function()
    {
      var self = this;
      self.$el.find('input[autofocus]').focus();
    },

    events:
    {
      "click @ui.save":         "onClickSave",
      "click @ui.delete":       "onClickDelete",
      "click @ui.cancel":       "onClickCancel",
      "click @ui.change_icon":  "onClickChangeIcon",
      "click @ui.change_media": "onClickChangeMedia",
      "click @ui.edit_events":  "onClickEditEvents",
      "change @ui.name":        "onChangeName",
      "change @ui.description": "onChangeDescription",
      "change @ui.continue_function": "onChangeContinueFunction",
    },

    onClickSave:function()
    {
      var self = this;

      self.model.save({},
      {
        create:function()
        {
          self.storePreviousAttributes();
          storage.add_game_object(self.model);
          vent.trigger("application:popup:hide");
        },

        update:function()
        {
          self.storePreviousAttributes();
          vent.trigger("application:popup:hide");
        }
      });
    },

    onClickCancel:function()
    {
      var self = this;
      delete self.previous_attributes.event_package_id;
      self.model.set(self.previous_attributes);
    },

    onClickDelete:function()
    {
      var self = this;
      self.model.destroy(
      {
        success: function()
        {
          vent.trigger("application:popup:hide");
        }
      });
    },

    onChangeName:        function() { var self = this; self.model.set("name",        self.ui.name.val());        },
    onChangeDescription: function() { var self = this; self.model.set("description", self.ui.description.val()); },
    onChangeContinueFunction: function() { var self = this; self.model.set("continue_function", self.ui.continue_function.find("option:selected").val()) },

    storePreviousAttributes: function()
    {
      var self = this;
      self.previous_attributes = _.clone(self.model.attributes)
    },

    unbindAssociations: function()
    {
      var self = this;
      self.stopListening(self.model.icon());
      self.stopListening(self.model.media());
    },

    bindAssociations: function()
    {
      var self = this;
      self.listenTo(self.model.icon(),  'change', self.render);
      self.listenTo(self.model.media(), 'change', self.render);
    },

    onClickChangeIcon: function()
    {
      var self = this;

      var game  = new Game({game_id: self.model.get("game_id")});
      var media = new MediaCollection([], {parent: game});

      function continueFetchingMedia()
      {
        media.fetch(
        {
          success: function()
          {
            media.unshift(self.model.default_icon());
            var icon_chooser = new MediaChooserView({collection: media, selected: self.model.icon(), context: self.model});

            icon_chooser.on("media:choose", function(media)
            {
              self.unbindAssociations();
              self.model.set("icon_media_id", media.id);
              self.bindAssociations();
              vent.trigger("application:popup:show", self, "Edit Plaque");
            });

            icon_chooser.on("cancel", function()
            {
              vent.trigger("application:popup:show", self, "Edit Plaque");
            });

            vent.trigger("application:popup:show", icon_chooser, "Choose Icon");
          }
        });
      }

      self.model.save({},
      {
        create:function()
        {
          self.storePreviousAttributes();
          storage.add_game_object(self.model);
          vent.trigger("application:popup:hide");
          continueFetchingMedia();
        },

        update:function()
        {
          self.storePreviousAttributes();
          vent.trigger("application:popup:hide");
          continueFetchingMedia();
        },
        success: function()
        {
          continueFetchingMedia();
        }
      });
    },

    onClickChangeMedia: function()
    {
      var self = this;

      var game  = new Game({game_id:self.model.get("game_id")});
      var media = new MediaCollection([], {parent:game});

      media.fetch(
      {
        success:function()
        {
          media.unshift(self.model.default_icon());

          var media_chooser = new MediaChooserView({collection:media, selected:self.model.media()});
          vent.trigger("application:popup:show", media_chooser, "Choose Media");

          media_chooser.on("media:choose", function(media)
          {
            self.unbindAssociations();
            self.model.set("media_id", media.id);
            self.bindAssociations();
            vent.trigger("application:popup:show", self, "Edit Plaque");
          });

          media_chooser.on("cancel", function()
          {
            vent.trigger("application:popup:show", self, "Edit Plaque");
          });
        }
      });
    },

    onClickEditEvents:function()
    {
      var self = this;

      var game = new Game({game_id:self.model.get("game_id")});

      var event_package;
      if(self.model.get("event_package_id") == 0) event_package = new EventPackage({game_id:game.id});
      else                                        event_package = new EventPackage({game_id:game.id, event_package_id:self.model.get("event_package_id")});
      var events = new EventsCollection([], {parent:event_package});

      var items  = new ItemsCollection([], {parent:game});

      $.when(
        items.fetch(),
        event_package.fetch(),
        events.fetch()
      ).done(
        function()
        {
          if(self.model.get("event_package_id") == 0)
          {
            event_package.save({},
            {
              success:function()
              {
                storage.add_game_object(event_package);
                self.model.set("event_package_id", event_package.id);
                self.model.save({}, {
                  create:function()
                  {
                    storage.add_game_object(self.model);
                  }
                });
                var events_editor = new EventPackageEditorView({model:event_package, collection:events, items:items});
                vent.trigger("application:popup:show", events_editor, "Player Modifier");
              }
            });
          }
          else
          {
            self.model.save({}, {});
            var events_editor = new EventPackageEditorView({model:event_package, collection:events, items:items});
            vent.trigger("application:popup:show", events_editor, "Player Modifier");
          }

        }
      );
    }
  });
});

<commit_msg>Fix plaque icon modal (copied from media modal)<commit_after>define([
  'underscore',
  'jquery',
  'backbone',
  'text!templates/plaque_editor.tpl',
  'collections/media',
  'collections/items',
  'models/game',
  'models/plaque',
  'models/event_package',
  'collections/events',
  'views/media_chooser',
  'views/event_package_editor',
  'vent',
  'storage',
],
function(
  _,
  $,
  Backbone,
  Template,
  MediaCollection,
  ItemsCollection,
  Game,
  Plaque,
  EventPackage,
  EventsCollection,
  MediaChooserView,
  EventPackageEditorView,
  vent,
  storage
)
{
  return Backbone.Marionette.CompositeView.extend(
  {
    template:_.template(Template),

    templateHelpers:function()
    {
      var self = this;
      return {
        is_new: self.model.isNew(),
        icon_thumbnail_url:  self.model.icon_thumbnail(),
        media_thumbnail_url: self.model.media_thumbnail(),
        option_selected: function(boolean_statement) { return boolean_statement ? "selected" : ""; },
        function_types: Plaque.function_types,
      };
    },

    ui:
    {
      "save":         ".save",
      "delete":       ".delete",
      "cancel":       ".cancel",
      "change_icon":  ".change-icon",
      "change_media": ".change-media",
      "edit_events":  ".edit-events",
      "name":         "#plaque-name",
      "description":  "#plaque-description",
      "continue_function": "#continue-function",
    },

    initialize: function(options)
    {
      var self = this;
      self.storePreviousAttributes();
      self.bindAssociations();
      self.on("popup:hide", self.onClickCancel);
    },

    onShow: function()
    {
      var self = this;
      self.$el.find('input[autofocus]').focus();
    },

    events:
    {
      "click @ui.save":         "onClickSave",
      "click @ui.delete":       "onClickDelete",
      "click @ui.cancel":       "onClickCancel",
      "click @ui.change_icon":  "onClickChangeIcon",
      "click @ui.change_media": "onClickChangeMedia",
      "click @ui.edit_events":  "onClickEditEvents",
      "change @ui.name":        "onChangeName",
      "change @ui.description": "onChangeDescription",
      "change @ui.continue_function": "onChangeContinueFunction",
    },

    onClickSave:function()
    {
      var self = this;

      self.model.save({},
      {
        create:function()
        {
          self.storePreviousAttributes();
          storage.add_game_object(self.model);
          vent.trigger("application:popup:hide");
        },

        update:function()
        {
          self.storePreviousAttributes();
          vent.trigger("application:popup:hide");
        }
      });
    },

    onClickCancel:function()
    {
      var self = this;
      delete self.previous_attributes.event_package_id;
      self.model.set(self.previous_attributes);
    },

    onClickDelete:function()
    {
      var self = this;
      self.model.destroy(
      {
        success: function()
        {
          vent.trigger("application:popup:hide");
        }
      });
    },

    onChangeName:        function() { var self = this; self.model.set("name",        self.ui.name.val());        },
    onChangeDescription: function() { var self = this; self.model.set("description", self.ui.description.val()); },
    onChangeContinueFunction: function() { var self = this; self.model.set("continue_function", self.ui.continue_function.find("option:selected").val()) },

    storePreviousAttributes: function()
    {
      var self = this;
      self.previous_attributes = _.clone(self.model.attributes)
    },

    unbindAssociations: function()
    {
      var self = this;
      self.stopListening(self.model.icon());
      self.stopListening(self.model.media());
    },

    bindAssociations: function()
    {
      var self = this;
      self.listenTo(self.model.icon(),  'change', self.render);
      self.listenTo(self.model.media(), 'change', self.render);
    },

    onClickChangeIcon: function()
    {
      var self = this;

      var game  = new Game({game_id:self.model.get("game_id")});
      var media = new MediaCollection([], {parent:game});

      media.fetch(
      {
        success:function()
        {
          media.unshift(self.model.default_icon());

          var media_chooser = new MediaChooserView({collection:media, selected:self.model.media()});
          vent.trigger("application:popup:show", media_chooser, "Choose Icon");

          media_chooser.on("media:choose", function(media)
          {
            self.unbindAssociations();
            self.model.set("icon_media_id", media.id);
            self.bindAssociations();
            vent.trigger("application:popup:show", self, "Edit Plaque");
          });

          media_chooser.on("cancel", function()
          {
            vent.trigger("application:popup:show", self, "Edit Plaque");
          });
        }
      });
    },

    onClickChangeMedia: function()
    {
      var self = this;

      var game  = new Game({game_id:self.model.get("game_id")});
      var media = new MediaCollection([], {parent:game});

      media.fetch(
      {
        success:function()
        {
          media.unshift(self.model.default_icon());

          var media_chooser = new MediaChooserView({collection:media, selected:self.model.media()});
          vent.trigger("application:popup:show", media_chooser, "Choose Media");

          media_chooser.on("media:choose", function(media)
          {
            self.unbindAssociations();
            self.model.set("media_id", media.id);
            self.bindAssociations();
            vent.trigger("application:popup:show", self, "Edit Plaque");
          });

          media_chooser.on("cancel", function()
          {
            vent.trigger("application:popup:show", self, "Edit Plaque");
          });
        }
      });
    },

    onClickEditEvents:function()
    {
      var self = this;

      var game = new Game({game_id:self.model.get("game_id")});

      // TODO: fix this so that if the event package doesn't exist, we make a new one

      var event_package;
      if(self.model.get("event_package_id") == 0) event_package = new EventPackage({game_id:game.id});
      else                                        event_package = new EventPackage({game_id:game.id, event_package_id:self.model.get("event_package_id")});
      var events = new EventsCollection([], {parent:event_package});

      var items  = new ItemsCollection([], {parent:game});

      $.when(
        items.fetch(),
        event_package.fetch(),
        events.fetch()
      ).done(
        function()
        {
          if(self.model.get("event_package_id") == 0)
          {
            event_package.save({},
            {
              success:function()
              {
                storage.add_game_object(event_package);
                self.model.set("event_package_id", event_package.id);
                self.model.save({}, {
                  create:function()
                  {
                    storage.add_game_object(self.model);
                  }
                });
                var events_editor = new EventPackageEditorView({model:event_package, collection:events, items:items});
                vent.trigger("application:popup:show", events_editor, "Player Modifier");
              }
            });
          }
          else
          {
            self.model.save({}, {});
            var events_editor = new EventPackageEditorView({model:event_package, collection:events, items:items});
            vent.trigger("application:popup:show", events_editor, "Player Modifier");
          }

        }
      );
    }
  });
});

<|endoftext|>


<commit_before>$(document).ready(function () {

    // Selecting some DOM elements for further handling

    var dom = {
        window: $(window),
        body: $('body'),
        navItem: $('.nav-item'),
        navBarLogo: $('.navbar-logo')
    };

    // Handling the navigation links

    dom.navItem.click(function () {
        var scrollElement = $(this).find('.nav-link').data('link'),
            scrollPosition = $(scrollElement).offset().top - 100;

        dom.body.animate({
            scrollTop: scrollPosition
        }, 500);
    });

    // Displaying the logo at the navigation bar

    dom.window.scroll(function () {

        if (dom.window.scrollTop() >= 300) {
            dom.navBarLogo.addClass('show');
        } else {
            dom.navBarLogo.removeClass('show');
        }
    });

    // Scroll to top on the logo click

    dom.navBarLogo.click(function () {
        dom.body.animate({
            scrollTop: 0
        }, 300);
    });

    // Promo stuff

    console.log('Powered by Jekyll Instagram Portfolio Theme');
    console.log('Project: https://github.com/portfolio-central/jekyll-instagram-portfolio-theme')
});<commit_msg>Adjust nav element scrolling functions<commit_after>$(document).ready(function () {

    // Selecting some DOM elements for further handling

    var dom = {
        window: $(window),
        body: $('body'),
        navItem: $('.nav-item'),
        navBarLogo: $('.navbar-logo')
    };

    // Handling the navigation links

    dom.navItem.click(function () {
        var scrollElement = $(this).find('.nav-link').data('link'),
            scrollPosition = $(scrollElement).offset().top - 100;

        $('html, body').animate({
            scrollTop: scrollPosition
        }, 500);
    });

    // Displaying the logo at the navigation bar

    dom.window.scroll(function () {

        if (dom.window.scrollTop() >= 300) {
            dom.navBarLogo.addClass('show');
        } else {
            dom.navBarLogo.removeClass('show');
        }
    });

    // Scroll to top on the logo click

    dom.navBarLogo.click(function () {
        $('html, body').animate({
            scrollTop: 0
        }, 300);
    });

    // Promo stuff

    console.log('Powered by Jekyll Instagram Portfolio Theme');
    console.log('Project: https://github.com/portfolio-central/jekyll-instagram-portfolio-theme')
});
<|endoftext|>


<commit_before>var assert = require('assert')

var _ = require('lodash')
var Q = require('q')

var ColorDefinition = require('./ColorDefinition')
var ColorValue = require('./ColorValue')
var ColorDataStorage = require('./ColorDataStorage')
var Transaction = require('./bitcoin').Transaction

/**
 * @class ColorData
 *
 * @param {ColorDataStorage} storage
 */
function ColorData(storage) {
  assert(storage instanceof ColorDataStorage,
    'Expected storage instance of ColorDataStorage, got ' + storage)

  this.storage = storage
}

/**
 * Return ColorValue currently present in ColorDataStorage
 *
 * @param {string} txId
 * @param {number} outIndex
 * @param {ColorDefinition} colorDefinition
 * @return {?ColorValue}
 */
ColorData.prototype.fetchColorValue = function(txId, outIndex, colorDefinition) {
  assert(Transaction.isTxId(txId), 'Expected transactionId txId, got ' + txId)
  assert(_.isNumber(outIndex), 'Expected number outIndex, got ' + outIndex)
  assert(colorDefinition instanceof ColorDefinition,
    'Expected ColorDefinition colorDefinition, got ' + colorDefinition)

  var colorValue = null

  var colorData = this.storage.get({
    colorId: colorDefinition.getColorId(),
    txId: txId,
    outIndex: outIndex
  })
  if (colorData !== null)
    colorValue = new ColorValue(colorDefinition, colorData.value)

  return colorValue
}

/**
 * @callback ColorData~scanTx
 * @param {?Error} error
 */

/**
 * Scan transaction to obtain color data for its outputs
 *
 * @param {Transaction} tx
 * @param {?number[]} outputIndices
 * @param {ColorDefinition} colorDefinition
 * @param {function} getTxFn
 * @param {ColorData~scanTx} cb Called on finished with params (error)
 */
ColorData.prototype.scanTx = function(tx, outputIndices, colorDefinition, getTxFn, cb) {
  assert(tx instanceof Transaction, 'Expected Transaction tx, got ' + tx)
  assert(_.isArray(outputIndices) || _.isNull(outputIndices), 'Expected Array|null outputIndices, got ' + outputIndices)
  if (_.isArray(outputIndices))
    assert(outputIndices.every(function(oi) { return _.isNumber(oi) }),
      'Expected outputIndices Array numbers, got ' + outputIndices)
  assert(colorDefinition instanceof ColorDefinition,
    'Expected ColorDefinition colorDefinition, got ' + colorDefinition)
  assert(_.isFunction(cb), 'Expected function cb, got ' + cb)

  var self = this

  Q.fcall(function() {
    var inColorValues = []
    var empty = true

    tx.ins.forEach(function(input) {
      var colorData = self.storage.get({
        colorId: colorDefinition.getColorId(),
        txId: Array.prototype.reverse.call(new Buffer(input.hash)).toString('hex'),
        outIndex: input.index
      })

      var colorValue = null
      if (colorData !== null) {
        empty = false
        colorValue = new ColorValue(colorDefinition, colorData.value)
      }
      inColorValues.push(colorValue)
    })

    if (empty && !colorDefinition.isSpecialTx(tx))
      return

    return Q.ninvoke(colorDefinition, 'runKernel', tx, inColorValues, getTxFn).then(function(outColorValues) {
      outColorValues.forEach(function(colorValue, index) {
        var skipAdd = colorValue === null || (outputIndices !== null && outputIndices.indexOf(index) === -1)

        if (!skipAdd)
          self.storage.add({
            colorId: colorDefinition.getColorId(),
            txId: tx.getId(),
            outIndex: index,
            value: colorValue.getValue()
          })
      })
    })

  }).done(function(){ cb(null) }, function(error) { cb(error) })
}

/**
 * @callback ColorData~getColorValue
 * @param {?Error} error
 * @param {?ColorValue} colorValue
 */

/**
 * For a given txId, outIndex and colorDefinition return ColorValue or null if
 *  colorDefinition not represented in given txOut
 *
 * @param {string} txId
 * @param {number} outIndex
 * @param {ColorDefinition} colorDefinition
 * @param {function} getTxFn
 * @param {ColorData~getColorValue} cb
 */
ColorData.prototype.getColorValue = function(txId, outIndex, colorDefinition, getTxFn, cb) {
  assert(Transaction.isTxId(txId), 'Expected transactionId txId, got ' + txId)
  assert(_.isNumber(outIndex), 'Expected number outIndex, got ' + outIndex)
  assert(colorDefinition instanceof ColorDefinition,
    'Expected ColorDefinition colorDefinition, got ' + colorDefinition)
  assert(_.isFunction(cb), 'Expected function cb, got ' + cb)

  var self = this

  Q.fcall(function() {
    var scannedOutputs = []

    function processOne(txId, outIndex) {
      if (scannedOutputs.indexOf(txId + outIndex) !== -1)
        return

      scannedOutputs.push(txId + outIndex)

      var colorValue = self.fetchColorValue(txId, outIndex, colorDefinition)
      if (colorValue !== null)
        return

      function processTx(tx) {
        return Q.nfcall(colorDefinition.constructor.getAffectingInputs, tx, [outIndex], getTxFn)
          .then(function(inputs) {
            var promise = Q()

            inputs.forEach(function(input) {
              var txId = Array.prototype.reverse.call(new Buffer(input.hash)).toString('hex')
              promise = promise.then(function() {
                return Q.fcall(processOne, txId, input.index)
              })
            })

            promise = promise.then(function() {
              return Q.ninvoke(self, 'scanTx', tx, null, colorDefinition, getTxFn)

            })

            return promise
          })
      }

      return Q.nfcall(getTxFn, txId).then(processTx)
    }

    return Q.fcall(processOne, txId, outIndex)

  }).then(function() {
    return self.fetchColorValue(txId, outIndex, colorDefinition)

  }).done(function(colorValue) { cb(null, colorValue) }, function(error) { cb(error) })
}

module.exports = ColorData
<commit_msg>ColorData.prototype.getColorValuesRaw (for incomplete transactions)<commit_after>var assert = require('assert')

var _ = require('lodash')
var Q = require('q')

var ColorDefinition = require('./ColorDefinition')
var ColorValue = require('./ColorValue')
var ColorDataStorage = require('./ColorDataStorage')
var Transaction = require('./bitcoin').Transaction

/**
 * @class ColorData
 *
 * @param {ColorDataStorage} storage
 */
function ColorData(storage) {
  assert(storage instanceof ColorDataStorage,
    'Expected storage instance of ColorDataStorage, got ' + storage)

  this.storage = storage
}

/**
 * Return ColorValue currently present in ColorDataStorage
 *
 * @param {string} txId
 * @param {number} outIndex
 * @param {ColorDefinition} colorDefinition
 * @return {?ColorValue}
 */
ColorData.prototype.fetchColorValue = function(txId, outIndex, colorDefinition) {
  assert(Transaction.isTxId(txId), 'Expected transactionId txId, got ' + txId)
  assert(_.isNumber(outIndex), 'Expected number outIndex, got ' + outIndex)
  assert(colorDefinition instanceof ColorDefinition,
    'Expected ColorDefinition colorDefinition, got ' + colorDefinition)

  var colorValue = null

  var colorData = this.storage.get({
    colorId: colorDefinition.getColorId(),
    txId: txId,
    outIndex: outIndex
  })
  if (colorData !== null)
    colorValue = new ColorValue(colorDefinition, colorData.value)

  return colorValue
}

ColorData.prototype.getColorValuesRaw = function (tx, colorDefinition, getTxFn, cb) {
    var inColorValuesQ = Q.all(
        tx.ins.map(function (input) {
            var txId = Array.prototype.reverse.call(new Buffer(input.hash)).toString('hex');
            return Q.ninvoke(self, txId, 'getColorValue',
                             input.index, colorDefinition, getTxFn);
            }));

    inColorvaluesQ.then(function (inColorValues) {
        return Q.ninvoke(colorDefinition, 'runKernel', tx, inColorValues, getTxFn);
    }).done(function(outColorValues) { cb(null, outColorValues); },
            function(error) { cb(error); });
};

/**
 * @callback ColorData~scanTx
 * @param {?Error} error
 */

/**
 * Scan transaction to obtain color data for its outputs
 *
 * @param {Transaction} tx
 * @param {?number[]} outputIndices
 * @param {ColorDefinition} colorDefinition
 * @param {function} getTxFn
 * @param {ColorData~scanTx} cb Called on finished with params (error)
 */
ColorData.prototype.scanTx = function(tx, outputIndices, colorDefinition, getTxFn, cb) {
  assert(tx instanceof Transaction, 'Expected Transaction tx, got ' + tx)
  assert(_.isArray(outputIndices) || _.isNull(outputIndices), 'Expected Array|null outputIndices, got ' + outputIndices)
  if (_.isArray(outputIndices))
    assert(outputIndices.every(function(oi) { return _.isNumber(oi) }),
      'Expected outputIndices Array numbers, got ' + outputIndices)
  assert(colorDefinition instanceof ColorDefinition,
    'Expected ColorDefinition colorDefinition, got ' + colorDefinition)
  assert(_.isFunction(cb), 'Expected function cb, got ' + cb)

  var self = this

  Q.fcall(function() {
    var inColorValues = []
    var empty = true

    tx.ins.forEach(function(input) {
      var colorData = self.storage.get({
        colorId: colorDefinition.getColorId(),
        txId: Array.prototype.reverse.call(new Buffer(input.hash)).toString('hex'),
        outIndex: input.index
      })

      var colorValue = null
      if (colorData !== null) {
        empty = false
        colorValue = new ColorValue(colorDefinition, colorData.value)
      }
      inColorValues.push(colorValue)
    })

    if (empty && !colorDefinition.isSpecialTx(tx))
      return

    return Q.ninvoke(colorDefinition, 'runKernel', tx, inColorValues, getTxFn).then(function(outColorValues) {
      outColorValues.forEach(function(colorValue, index) {
        var skipAdd = colorValue === null || (outputIndices !== null && outputIndices.indexOf(index) === -1)

        if (!skipAdd)
          self.storage.add({
            colorId: colorDefinition.getColorId(),
            txId: tx.getId(),
            outIndex: index,
            value: colorValue.getValue()
          })
      })
    })

  }).done(function(){ cb(null) }, function(error) { cb(error) })
}

/**
 * @callback ColorData~getColorValue
 * @param {?Error} error
 * @param {?ColorValue} colorValue
 */

/**
 * For a given txId, outIndex and colorDefinition return ColorValue or null if
 *  colorDefinition not represented in given txOut
 *
 * @param {string} txId
 * @param {number} outIndex
 * @param {ColorDefinition} colorDefinition
 * @param {function} getTxFn
 * @param {ColorData~getColorValue} cb
 */
ColorData.prototype.getColorValue = function(txId, outIndex, colorDefinition, getTxFn, cb) {
  assert(Transaction.isTxId(txId), 'Expected transactionId txId, got ' + txId)
  assert(_.isNumber(outIndex), 'Expected number outIndex, got ' + outIndex)
  assert(colorDefinition instanceof ColorDefinition,
    'Expected ColorDefinition colorDefinition, got ' + colorDefinition)
  assert(_.isFunction(cb), 'Expected function cb, got ' + cb)

  var self = this

  Q.fcall(function() {
    var scannedOutputs = []

    function processOne(txId, outIndex) {
      if (scannedOutputs.indexOf(txId + outIndex) !== -1)
        return

      scannedOutputs.push(txId + outIndex)

      var colorValue = self.fetchColorValue(txId, outIndex, colorDefinition)
      if (colorValue !== null)
        return

      function processTx(tx) {
        return Q.nfcall(colorDefinition.constructor.getAffectingInputs, tx, [outIndex], getTxFn)
          .then(function(inputs) {
            var promise = Q()

            inputs.forEach(function(input) {
              var txId = Array.prototype.reverse.call(new Buffer(input.hash)).toString('hex')
              promise = promise.then(function() {
                return Q.fcall(processOne, txId, input.index)
              })
            })

            promise = promise.then(function() {
              return Q.ninvoke(self, 'scanTx', tx, null, colorDefinition, getTxFn)

            })

            return promise
          })
      }

      return Q.nfcall(getTxFn, txId).then(processTx)
    }

    return Q.fcall(processOne, txId, outIndex)

  }).then(function() {
    return self.fetchColorValue(txId, outIndex, colorDefinition)

  }).done(function(colorValue) { cb(null, colorValue) }, function(error) { cb(error) })
}

module.exports = ColorData
<|endoftext|>


<commit_before>/*eslint-env node, mocha */

var path   = require('path');
var fs     = require('fs-extra');
var chai   = require('chai');
var expect = chai.expect;

chai.use(require('chai-fs'));
chai.should();

var MOCK_PROJECT_DIR = path.join(process.cwd(), 'test', 'mock-project');
var STYLE_SRC_DIR    = path.join(MOCK_PROJECT_DIR, '_source', 'styles');
var STYLE_DEST_DIR   = path.join(MOCK_PROJECT_DIR, 'public', '_client', 'styles');

var MAIN_SCSS_FILEPATH          = path.join(STYLE_SRC_DIR, 'main.scss');
var MAIN_CSS_FILEPATH           = path.join(STYLE_DEST_DIR, 'main.css');
var MAIN_CSS_SOURCEMAP_FILEPATH = path.join(STYLE_DEST_DIR, 'main.css.map');

var IE8_SCSS_FILEPATH          = path.join(STYLE_SRC_DIR, 'ie8.scss');
var IE8_CSS_FILEPATH           = path.join(STYLE_DEST_DIR, 'ie8.css');
var IE8_CSS_SOURCEMAP_FILEPATH = path.join(STYLE_DEST_DIR, 'ie8.css.map');

process.chdir(MOCK_PROJECT_DIR);

var gulprunner = require(path.resolve(process.cwd(), 'gulprunner.js'));

function cleanUp() {
	fs.remove(MAIN_SCSS_FILEPATH);
	fs.remove(MAIN_CSS_FILEPATH);
	fs.remove(MAIN_CSS_SOURCEMAP_FILEPATH);

	fs.remove(IE8_SCSS_FILEPATH);
	fs.remove(IE8_CSS_FILEPATH);
	fs.remove(IE8_CSS_SOURCEMAP_FILEPATH);
}

function assertGoldMaster(generatedPath, master) {
	var goldMasterPath = path.resolve(path.join('../', 'gold-master', master));
	var goldMaster     = fs.readFileSync(goldMasterPath, {encoding: 'utf8'});
	var generated      = fs.readFileSync(generatedPath, {encoding: 'utf8'});

	expect(goldMaster).to.equal(generated);
}

describe('As a gulpfile', function() {
	describe('when a task is included', function() {
		var basicrunner;

		before(function(done) {
			basicrunner = require(path.resolve(process.cwd(), 'basicrunner.js'));

			done();
		});

		it('should add one task to the default group', function() {
			expect(basicrunner.tasks.default.length).to.equal(1);
		});

		it('should add the sass task to the default group', function() {
			expect(basicrunner.tasks.default[0]).to.equal('sass');
		});

		it('should add one task to the watch group', function() {
			expect(basicrunner.tasks.watch.length).to.equal(1);
		});

		it('should add the watch:sass task to the watch group', function() {
			expect(basicrunner.tasks.watch[0]).to.equal('watch:sass');
		});

		it('should add one clean path to the clean config', function() {
			expect(basicrunner.config.cleanPaths.length).to.equal(1);
		});

		it('should add the generated styles path to the clean config', function() {
			var relative = path.relative(process.cwd(), basicrunner.config.cleanPaths[0]);
			expect(relative).to.equal(path.join('public', '_client', 'styles'));
		});
	});
})

describe('As a user of the cartridge-sass module', function() {

	this.timeout(10000);

	describe('when `gulp sass` is run WITHOUT production flag', function() {

		before(function(done) {
			gulprunner.setDev();
			gulprunner.run(done);
		});

		after(function() {
			cleanUp();
		});

		it('should generate the main.scss file in the _source dir', function() {
			expect(MAIN_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css file to the public styles folder', function() {
			expect(MAIN_CSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css.map sourcemap file to the public styles folder', function() {
			expect(MAIN_CSS_SOURCEMAP_FILEPATH).to.be.a.file();
		});

		it('should generate the ie8.scss file in the _source dir', function() {
			expect(IE8_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the ie8.css file to the public styles folder', function() {
			expect(IE8_CSS_FILEPATH).to.be.a.file();
		});

		it('should add the ie8.css.map sourcemap file to the public styles folder', function() {
			expect(IE8_CSS_SOURCEMAP_FILEPATH).to.be.a.file();
		});

		it('should generate the correct css', function() {
			assertGoldMaster(MAIN_CSS_FILEPATH, 'dev.css');
			assertGoldMaster(IE8_CSS_FILEPATH, 'ie8-dev.css');
		});

	});

	describe('when `gulp sass` is run WITH production flag', function() {

		before(function(done) {
			gulprunner.setProd();
			gulprunner.run(done);
		});

		after(function() {
			cleanUp();
		});

		it('should generate the main.scss file in the _source dir', function() {
			expect(MAIN_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css file to the public styles folder', function() {
			expect(MAIN_CSS_FILEPATH).to.be.a.file();
		});

		it('should not add the main.css.map sourcemap file to the public styles folder', function() {
			expect(MAIN_CSS_SOURCEMAP_FILEPATH).to.not.be.a.path();
		});

		it('should generate the main.scss file in the _source dir', function() {
			expect(IE8_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css file to the public styles folder', function() {
			expect(IE8_CSS_FILEPATH).to.be.a.file();
		});

		it('should not add the main.css.map sourcemap file to the public styles folder', function() {
			expect(IE8_CSS_SOURCEMAP_FILEPATH).to.not.be.a.path();
		});

		it('should generate the correct css', function() {
			assertGoldMaster(MAIN_CSS_FILEPATH, 'prod.css');
			assertGoldMaster(IE8_CSS_FILEPATH, 'ie8-prod.css');
		});

	});

});
<commit_msg>refactor: Pass cleanUp reference to mocha after. Shorten readFileSync<commit_after>/*eslint-env node, mocha */

var path   = require('path');
var fs     = require('fs-extra');
var chai   = require('chai');
var expect = chai.expect;

chai.use(require('chai-fs'));
chai.should();

var MOCK_PROJECT_DIR = path.join(process.cwd(), 'test', 'mock-project');
var STYLE_SRC_DIR    = path.join(MOCK_PROJECT_DIR, '_source', 'styles');
var STYLE_DEST_DIR   = path.join(MOCK_PROJECT_DIR, 'public', '_client', 'styles');

var MAIN_SCSS_FILEPATH          = path.join(STYLE_SRC_DIR, 'main.scss');
var MAIN_CSS_FILEPATH           = path.join(STYLE_DEST_DIR, 'main.css');
var MAIN_CSS_SOURCEMAP_FILEPATH = path.join(STYLE_DEST_DIR, 'main.css.map');

var IE8_SCSS_FILEPATH          = path.join(STYLE_SRC_DIR, 'ie8.scss');
var IE8_CSS_FILEPATH           = path.join(STYLE_DEST_DIR, 'ie8.css');
var IE8_CSS_SOURCEMAP_FILEPATH = path.join(STYLE_DEST_DIR, 'ie8.css.map');

process.chdir(MOCK_PROJECT_DIR);

var gulprunner = require(path.resolve(process.cwd(), 'gulprunner.js'));

function cleanUp() {
	fs.remove(MAIN_SCSS_FILEPATH);
	fs.remove(MAIN_CSS_FILEPATH);
	fs.remove(MAIN_CSS_SOURCEMAP_FILEPATH);

	fs.remove(IE8_SCSS_FILEPATH);
	fs.remove(IE8_CSS_FILEPATH);
	fs.remove(IE8_CSS_SOURCEMAP_FILEPATH);
}

function assertGoldMaster(generatedPath, master) {
	var goldMasterPath = path.resolve(path.join('../', 'gold-master', master));
	var goldMaster     = fs.readFileSync(goldMasterPath, 'utf8');
	var generated      = fs.readFileSync(generatedPath, 'utf8');

	expect(goldMaster).to.equal(generated);
}

describe('As a gulpfile', function() {
	describe('when a task is included', function() {
		var basicrunner;

		before(function(done) {
			basicrunner = require(path.resolve(process.cwd(), 'basicrunner.js'));

			done();
		});

		it('should add one task to the default group', function() {
			expect(basicrunner.tasks.default.length).to.equal(1);
		});

		it('should add the sass task to the default group', function() {
			expect(basicrunner.tasks.default[0]).to.equal('sass');
		});

		it('should add one task to the watch group', function() {
			expect(basicrunner.tasks.watch.length).to.equal(1);
		});

		it('should add the watch:sass task to the watch group', function() {
			expect(basicrunner.tasks.watch[0]).to.equal('watch:sass');
		});

		it('should add one clean path to the clean config', function() {
			expect(basicrunner.config.cleanPaths.length).to.equal(1);
		});

		it('should add the generated styles path to the clean config', function() {
			var relative = path.relative(process.cwd(), basicrunner.config.cleanPaths[0]);
			expect(relative).to.equal(path.join('public', '_client', 'styles'));
		});
	});
})

describe('As a user of the cartridge-sass module', function() {

	this.timeout(10000);

	describe('when `gulp sass` is run WITHOUT production flag', function() {

		before(function(done) {
			gulprunner.setDev();
			gulprunner.run(done);
		});

		after(cleanUp);

		it('should generate the main.scss file in the _source dir', function() {
			expect(MAIN_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css file to the public styles folder', function() {
			expect(MAIN_CSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css.map sourcemap file to the public styles folder', function() {
			expect(MAIN_CSS_SOURCEMAP_FILEPATH).to.be.a.file();
		});

		it('should generate the ie8.scss file in the _source dir', function() {
			expect(IE8_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the ie8.css file to the public styles folder', function() {
			expect(IE8_CSS_FILEPATH).to.be.a.file();
		});

		it('should add the ie8.css.map sourcemap file to the public styles folder', function() {
			expect(IE8_CSS_SOURCEMAP_FILEPATH).to.be.a.file();
		});

		it('should generate the correct css', function() {
			assertGoldMaster(MAIN_CSS_FILEPATH, 'dev.css');
			assertGoldMaster(IE8_CSS_FILEPATH, 'ie8-dev.css');
		});

	});

	describe('when `gulp sass` is run WITH production flag', function() {

		before(function(done) {
			gulprunner.setProd();
			gulprunner.run(done);
		});

		after(cleanUp);

		it('should generate the main.scss file in the _source dir', function() {
			expect(MAIN_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css file to the public styles folder', function() {
			expect(MAIN_CSS_FILEPATH).to.be.a.file();
		});

		it('should not add the main.css.map sourcemap file to the public styles folder', function() {
			expect(MAIN_CSS_SOURCEMAP_FILEPATH).to.not.be.a.path();
		});

		it('should generate the main.scss file in the _source dir', function() {
			expect(IE8_SCSS_FILEPATH).to.be.a.file();
		});

		it('should add the main.css file to the public styles folder', function() {
			expect(IE8_CSS_FILEPATH).to.be.a.file();
		});

		it('should not add the main.css.map sourcemap file to the public styles folder', function() {
			expect(IE8_CSS_SOURCEMAP_FILEPATH).to.not.be.a.path();
		});

		it('should generate the correct css', function() {
			assertGoldMaster(MAIN_CSS_FILEPATH, 'prod.css');
			assertGoldMaster(IE8_CSS_FILEPATH, 'ie8-prod.css');
		});

	});

});
<|endoftext|>