<commit_before>/**
 * Created by ndyumin on 15.09.2016.
 */

const {removeItem} = require('./arrays');
const {fromCallbacks, notifyAll} = require('./observers');
const symbolObservable = require('symbol-observable');

function project(events, initial) {
    return events.reduce(function (state, event) {
        return event.reduce(state, event.update);
    }, initial);
}

const eventCreatorFactory = reduce => update => ({
    reduce,
    update
});

const commandCreatorFactory = executor => executor;

function store(initial) {
    let events = [];
    let replicas = [];

    return {
        [symbolObservable]: function () {
            return this;
        },
        _eventLog (observer) {
            if (typeof observer === 'function') {
                observer = fromCallbacks(...arguments);
            }
            events.forEach(observer.next);
            replicas.push(observer);

            return {
                unsubscribe() {
                    replicas = removeItem(replicas, observer);
                }
            };
        },
        subscribe(observer) {
            if (typeof observer === 'function') {
                observer = fromCallbacks(...arguments);
            }

            return this.view(project).subscribe(observer);
        },
        plug(observable, reducer) {
            const event = this.eventCreatorFactory(reducer);
            return observable.subscribe({
                next: event
            });
        },
        view(projectFn) {
            let _viewObservers = [];
            const eventLog = this._eventLog;

            return {
                subscribe (observer) {
                    if (typeof observer === 'function') {
                        observer = fromCallbacks(...arguments);
                    }
                    _viewObservers.push(observer);
                    const subs = eventLog(function () {
                        observer.next(projectFn(events, initial));
                    });

                    return {
                        unsubscribe() {
                            subs.unsubscribe();
                            _viewObservers = removeItem(_viewObservers, observer);
                        }
                    };
                }
            }
        },
        transaction() {
            const _branchRev = events.length;
            const _altEvents = [];
            const branch = store(initial);
            const subs = this._eventLog(branch.dispatch);
            const bSubs = branch._eventLog(ev => _altEvents.push(ev));
            return {
                store: () => branch,
                dispatch: branch.dispatch,
                commit: () => {
                    subs.unsubscribe();
                    bSubs.unsubscribe();
                    events = events.slice(0, _branchRev).concat(_altEvents);
                    _altEvents.length = 0;
                    notifyAll(replicas, eventCreatorFactory(s=>s)())
                },
                cancel: () => {
                    subs.unsubscribe();
                    bSubs.unsubscribe();
                    _altEvents.length = 0;
                }
            };
        },
        dispatch(event) {
            events.push(event);
            notifyAll(replicas, event);
        },
        commandCreatorFactory,
        eventCreatorFactory(reduce) {
            return update =>
                this.dispatch({
                    reduce,
                    update
                });
        }
    };
}

module.exports = {
    store,
    eventCreatorFactory,
    commandCreatorFactory,
    defaultProjection: project
};<commit_msg>- notify of an initial value on a subscription<commit_after>/**
 * Created by ndyumin on 15.09.2016.
 */

const {removeItem} = require('./arrays');
const {fromCallbacks, notifyAll} = require('./observers');
const symbolObservable = require('symbol-observable');

function project(events, initial) {
    return events.reduce(function (state, event) {
        return event.reduce(state, event.update);
    }, initial);
}

const eventCreatorFactory = reduce => update => ({
    reduce,
    update
});

const commandCreatorFactory = executor => executor;

function store(initial) {
    let events = [];
    let replicas = [];

    return {
        [symbolObservable]: function () {
            return this;
        },
        _eventLog (observer) {
            if (typeof observer === 'function') {
                observer = fromCallbacks(...arguments);
            }
            events.forEach(observer.next);
            replicas.push(observer);

            return {
                unsubscribe() {
                    replicas = removeItem(replicas, observer);
                }
            };
        },
        subscribe(observer) {
            if (typeof observer === 'function') {
                observer = fromCallbacks(...arguments);
            }

            return this.view(project).subscribe(observer);
        },
        plug(observable, reducer) {
            const event = this.eventCreatorFactory(reducer);
            return observable.subscribe({
                next: event
            });
        },
        view(projectFn) {
            let _viewObservers = [];
            const onEvent = this._eventLog;

            return {
                subscribe (observer) {
                    if (typeof observer === 'function') {
                        observer = fromCallbacks(...arguments);
                    }
                    _viewObservers.push(observer);
                    const projectAndNotify = () =>
                        observer.next(projectFn(events, initial));

                    projectAndNotify();

                    const subscription = onEvent(projectAndNotify);

                    return {
                        unsubscribe() {
                            subscription.unsubscribe();
                            _viewObservers = removeItem(_viewObservers, observer);
                        }
                    };
                }
            }
        },
        transaction() {
            const _branchRev = events.length;
            const _altEvents = [];
            const branch = store(initial);
            const subs = this._eventLog(branch.dispatch);
            const bSubs = branch._eventLog(ev => _altEvents.push(ev));
            return {
                store: () => branch,
                dispatch: branch.dispatch,
                commit: () => {
                    subs.unsubscribe();
                    bSubs.unsubscribe();
                    events = events.slice(0, _branchRev).concat(_altEvents);
                    _altEvents.length = 0;
                    notifyAll(replicas, eventCreatorFactory(s=>s)())
                },
                cancel: () => {
                    subs.unsubscribe();
                    bSubs.unsubscribe();
                    _altEvents.length = 0;
                }
            };
        },
        dispatch(event) {
            events.push(event);
            notifyAll(replicas, event);
        },
        commandCreatorFactory,
        eventCreatorFactory(reduce) {
            return update =>
                this.dispatch({
                    reduce,
                    update
                });
        }
    };
}

module.exports = {
    store,
    eventCreatorFactory,
    commandCreatorFactory,
    defaultProjection: project
};<|endoftext|>


<commit_before>let _state = {};
let _middlewares = [];

export default {
  get state() {
    return Object.assign({}, _state);
  },
  setState: (partialState) => {
    if(typeof partialState !== 'object') {
      throw new TypeError('setState() takes an object of state variables to update');
    }
    _state = Object.assign({}, _state, partialState);
  },
  overwriteState: (newState) => {
    _state = Object.assign({}, newState);
  },
  register: (...middlewares) => {
    _middlewares = _middlewares.concat(middlewares);
    let chain = _middlewares.reduceRight((f, g) => (next) => f(g(next)))((partialState) => _state = Object.assign({}, _state, partialState));
    module.exports.setState = chain;
    global['$'].setState = chain;
  },
};
<commit_msg>$ fix<commit_after>let _state = {};
let _middlewares = [];

export default {
  get state() {
    return Object.assign({}, _state);
  },
  setState: (partialState) => {
    if(typeof partialState !== 'object') {
      throw new TypeError('setState() takes an object of state variables to update');
    }
    _state = Object.assign({}, _state, partialState);
  },
  overwriteState: (newState) => {
    _state = Object.assign({}, newState);
  },
  register: (...middlewares) => {
    _middlewares = _middlewares.concat(middlewares);
    let chain = _middlewares.reduceRight((f, g) => next => f(g(next)))(partialState => _state = Object.assign({}, _state, partialState));
    module.exports.setState = chain;
    global['$'].setState = chain;
    module.exports.overwriteState = _middlewares.reduceRight((f, g) => {
      if(g.name !== '__DEVTOOLS__') {
        return next => f(g(next));
      }
      else {
        return f;
      }
    })(newState => _state = Object.assign({}, newState));
  },
};
<|endoftext|>


<commit_before>/*
  Copyright (C) 2012 Tim Disney <tim@disnet.me>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

(function (root, factory) {
    if (typeof exports === 'object') {
        // CommonJS
        var parser = require("./parser");
        var expander = require("./expander");
        var syn = require("./syntax");
        var codegen = require("escodegen");

        var path = require('path');
        var fs   = require('fs');
        var lib  = path.join(path.dirname(fs.realpathSync(__filename)), "../macros");

        var stxcaseModule = fs.readFileSync(lib + "/stxcase.js", 'utf8');

        factory(exports, parser, expander, syn, stxcaseModule, codegen);

        // Alow require('./example') for an example.sjs file.
        require.extensions['.sjs'] = function(module, filename) {
            var content = require('fs').readFileSync(filename, 'utf8');
            module._compile(codegen.generate(exports.parse(content)), filename);
        };
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['exports', './parser', './expander', './syntax', 'text!./stxcase.js'], factory);
    }
}(this, function (exports, parser, expander, syn, stxcaseModule, gen) {
    var codegen = gen || escodegen;

    // fun (Str) -> [...CSyntax]
    function expand(code, globalMacros, maxExpands) {
        var program, toString;
        globalMacros = globalMacros || '';

        toString = String;
        if (typeof code !== 'string' && !(code instanceof String)) {
            code = toString(code);
        }

        var source = code;

        if (source.length > 0) {
            if (typeof source[0] === 'undefined') {
                // Try first to convert to a string. This is good as fast path
                // for old IE which understands string indexing for string
                // literals only and not for string object.
                if (code instanceof String) {
                    source = code.valueOf();
                }

                // Force accessing the characters via an array.
                if (typeof source[0] === 'undefined') {
                    source = stringToArray(code);
                }
            }
        }

        var readTree = parser.read(source);
        try {
            return expander.expand(readTree, stxcaseModule + '\n' + globalMacros, maxExpands);
        } catch(err) {
            if (err instanceof syn.MacroSyntaxError) {
                throw new SyntaxError(syn.printSyntaxError(source, err));
            } else {
                throw err;
            }
        }
    }

    // fun (Str, {}) -> AST
    function parse(code, globalMacros, maxExpands) {
        if (code === "") {
            // old version of esprima doesn't play nice with the empty string
            // and loc/range info so until we can upgrade hack in a single space
            code = " ";
        }

        return parser.parse(expand(code, globalMacros, maxExpands));
    }

    // fun ([...CSyntax]) -> String
    function prettyPrint(stxarr, shouldResolve) {
        var indent = 0;
        var unparsedLines = stxarr.reduce(function(acc, stx) {
            var s = shouldResolve ? expander.resolve(stx) : stx.token.value;
            // skip the end of file token
            if (stx.token.type === parser.Token.EOF) { return acc; }

            if(s == '{') {
                acc[0].str += ' ' + s;
                indent++;
                acc.unshift({ indent: indent, str: '' });
            }
            else if(s == '}') {
                indent--;
                acc.unshift({ indent: indent, str: s });
                acc.unshift({ indent: indent, str: '' });
            }
            else if(s == ';') {
                acc[0].str += s;
                acc.unshift({ indent: indent, str: '' });
            }
            else {
                acc[0].str += (acc[0].str ? ' ' : '') + s;
            }

            return acc;
        }, [{ indent: 0, str: '' }]);

        return unparsedLines.reduce(function(acc, line) {
            var ind = '';
            while(ind.length < line.indent * 2) {
                ind += ' ';
            }
            return ind + line.str + '\n' + acc;
        }, '');
    }

    exports.expand = expand;
    exports.parse = parse;
    exports.prettyPrint = prettyPrint;

    // (Str, {sourceMap: ?Bool, filename: ?Str})
    //    -> { code: Str, sourceMap: ?Str }
    exports.compile = function compile(code, options) {
        var output;
        options = options || {};

        var ast = parse(code, options.macros);

        if (options.sourceMap) {
            output = codegen.generate(ast, {
                comment: true,
                sourceMap: options.filename,
                sourceMapWithCode: true
            });

            return {
                code: output.code,
                sourceMap: output.map.toString()
            };
        }
        return {
            code: codegen.generate(ast, {
                comment: true
            })
        };
    }
}));
<commit_msg>quotes around strings in pretty print<commit_after>/*
  Copyright (C) 2012 Tim Disney <tim@disnet.me>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

(function (root, factory) {
    if (typeof exports === 'object') {
        // CommonJS
        var parser = require("./parser");
        var expander = require("./expander");
        var syn = require("./syntax");
        var codegen = require("escodegen");

        var path = require('path');
        var fs   = require('fs');
        var lib  = path.join(path.dirname(fs.realpathSync(__filename)), "../macros");

        var stxcaseModule = fs.readFileSync(lib + "/stxcase.js", 'utf8');

        factory(exports, parser, expander, syn, stxcaseModule, codegen);

        // Alow require('./example') for an example.sjs file.
        require.extensions['.sjs'] = function(module, filename) {
            var content = require('fs').readFileSync(filename, 'utf8');
            module._compile(codegen.generate(exports.parse(content)), filename);
        };
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['exports', './parser', './expander', './syntax', 'text!./stxcase.js'], factory);
    }
}(this, function (exports, parser, expander, syn, stxcaseModule, gen) {
    var codegen = gen || escodegen;

    // fun (Str) -> [...CSyntax]
    function expand(code, globalMacros, maxExpands) {
        var program, toString;
        globalMacros = globalMacros || '';

        toString = String;
        if (typeof code !== 'string' && !(code instanceof String)) {
            code = toString(code);
        }

        var source = code;

        if (source.length > 0) {
            if (typeof source[0] === 'undefined') {
                // Try first to convert to a string. This is good as fast path
                // for old IE which understands string indexing for string
                // literals only and not for string object.
                if (code instanceof String) {
                    source = code.valueOf();
                }

                // Force accessing the characters via an array.
                if (typeof source[0] === 'undefined') {
                    source = stringToArray(code);
                }
            }
        }

        var readTree = parser.read(source);
        try {
            return expander.expand(readTree, stxcaseModule + '\n' + globalMacros, maxExpands);
        } catch(err) {
            if (err instanceof syn.MacroSyntaxError) {
                throw new SyntaxError(syn.printSyntaxError(source, err));
            } else {
                throw err;
            }
        }
    }

    // fun (Str, {}) -> AST
    function parse(code, globalMacros, maxExpands) {
        if (code === "") {
            // old version of esprima doesn't play nice with the empty string
            // and loc/range info so until we can upgrade hack in a single space
            code = " ";
        }

        return parser.parse(expand(code, globalMacros, maxExpands));
    }

    // fun ([...CSyntax]) -> String
    function prettyPrint(stxarr, shouldResolve) {
        var indent = 0;
        var unparsedLines = stxarr.reduce(function(acc, stx) {
            var s = shouldResolve ? expander.resolve(stx) : stx.token.value;
            // skip the end of file token
            if (stx.token.type === parser.Token.EOF) { return acc; }

            if(stx.token.type === parser.Token.StringLiteral) {
                s = '"' + s + '"';
            }

            if(s == '{') {
                acc[0].str += ' ' + s;
                indent++;
                acc.unshift({ indent: indent, str: '' });
            }
            else if(s == '}') {
                indent--;
                acc.unshift({ indent: indent, str: s });
                acc.unshift({ indent: indent, str: '' });
            }
            else if(s == ';') {
                acc[0].str += s;
                acc.unshift({ indent: indent, str: '' });
            }
            else {
                acc[0].str += (acc[0].str ? ' ' : '') + s;
            }

            return acc;
        }, [{ indent: 0, str: '' }]);

        return unparsedLines.reduce(function(acc, line) {
            var ind = '';
            while(ind.length < line.indent * 2) {
                ind += ' ';
            }
            return ind + line.str + '\n' + acc;
        }, '');
    }

    exports.expand = expand;
    exports.parse = parse;
    exports.prettyPrint = prettyPrint;

    // (Str, {sourceMap: ?Bool, filename: ?Str})
    //    -> { code: Str, sourceMap: ?Str }
    exports.compile = function compile(code, options) {
        var output;
        options = options || {};

        var ast = parse(code, options.macros);

        if (options.sourceMap) {
            output = codegen.generate(ast, {
                comment: true,
                sourceMap: options.filename,
                sourceMapWithCode: true
            });

            return {
                code: output.code,
                sourceMap: output.map.toString()
            };
        }
        return {
            code: codegen.generate(ast, {
                comment: true
            })
        };
    }
}));
<|endoftext|>


<commit_before>'use strict';

var mainApp = angular.module('mainApp', ['service.api', 'service.session', 'service.outsider', 'service.analysis', 'service.utility', 'service.options', 'ui.bootstrap', 'highcharts-ng', 'ngCookies', 'ngRoute']);

mainApp.config(function ($routeProvider, $httpProvider) {

    //================================================
    // Add an interceptor for AJAX errors
    //================================================
    $httpProvider.responseInterceptors.push(function($q, $location) {
        return function(promise) {
            return promise.then(
                // Success: just return the response
                function(response){
                    return response;
                },
                // Error: check the error status to get only the 401
                function(response) {
                    if (response.status === 401)
                        $location.url('/login');
                    return $q.reject(response);
                }
            );
        }
    });
    //================================================

    $httpProvider.defaults.withCredentials = true;

    $routeProvider
        .when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/dashboard', {
            templateUrl: 'views/dashboard.html',
            controller: 'DashboardCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/contact', {
            templateUrl: 'views/contact.html',
            controller: 'ContactCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/word-lookup', {
            templateUrl: 'views/word-lookup.html',
            controller: 'WordLookupCtrl',
            resolve: { user: mainApp.resolveUser }
        })

        .when('/word-lookup-quiz', {
            templateUrl: 'views/games/word-lookup-quiz.html',
            controller: 'WordLookupQuizCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/word-game', {
            templateUrl: 'views/games/word-game.html',
            controller: 'WordLookupQuizOnlineCtrl',
            resolve: { user: mainApp.resolveUser }
        })

        .when('/login', {
            templateUrl: 'views/member/login.html',
            controller: 'LoginCtrl'
        })
        .when('/logout', {
            templateUrl: 'views/member/logout.html',
            controller: 'LogoutCtrl'
        })
        .when('/register', {
            templateUrl: 'views/member/register.html',
            controller: 'RegisterCtrl'
        })

        .otherwise({
            redirectTo: '/'
        });

});

// EXTEND Classes here
mainApp.config(function ($routeProvider) {

    // check if dates are the same
    // it only checks: (day, month and year)
    Date.prototype.sameDateAs = function(pDate){
        return ((this.getFullYear()==pDate.getFullYear())&&(this.getMonth()==pDate.getMonth())&&(this.getDate()==pDate.getDate()));
    }

});

mainApp.run(function ($rootScope) {
    // var server = {mode: 'local', url: 'http://localhost:3000'};
    var server = {mode: 'server', url: 'http://smart-read-api.aws.af.cm'};
    chrome.storage.local.set({'server': server}, function(){});
    $rootScope.server = server;
});

mainApp.resolveUser = function($q, $route, $rootScope, $location, session){
    var defer = $q.defer();

    // if already have $rootScope.user, just return it
    if($rootScope.user){
        defer.resolve($rootScope.user)
    }

    // otherwise check if chrome storage has user session info
    else {
        session.check(function(user){
            // if it has, then return it
            if(user)
                defer.resolve(user);

            // otherwise, redirect to login
            else {
                defer.reject();
                $location.path('/login');
            }
        });
    }

    return defer.promise;
}

mainApp.filter('oneZeroToYesNo', function() {
    return function(input) {
        return input == 1 ? 'Yes' : 'No';
    };
});

mainApp.filter('oneZeroToSuccessFail', function() {
    return function(input) {
        return input == 1 ? 'Success' : 'Fail';
    };
});<commit_msg>new angular route<commit_after>'use strict';

// var server = {mode: 'local', url: 'http://localhost:3000'};
var server = {mode: 'server', url: 'http://smart-read-api.aws.af.cm'};
chrome.storage.local.set({'server': server}, function(){});

var mainApp = angular.module('mainApp', ['service.api', 'service.session', 'service.outsider', 'service.analysis', 'service.utility', 'service.options', 'ui.bootstrap', 'highcharts-ng', 'ngCookies', 'ngRoute']);

mainApp.config(function ($routeProvider, $httpProvider) {

    //================================================
    // Add an interceptor for AJAX errors
    //================================================
    $httpProvider.responseInterceptors.push(function($q, $location) {
        return function(promise) {
            return promise.then(
                // Success: just return the response
                function(response){
                    return response;
                },
                // Error: check the error status to get only the 401
                function(response) {
                    var requestedUrl = response.config.url;

                    if (response.status === 401)
                        $location.url('/login');

                    else if(response.status === 404 && requestedUrl.indexOf(server.url) != -1 )
                        $location.url('/error/server-down');

                    return $q.reject(response);
                }
            );
        }
    });
    //================================================

    $httpProvider.defaults.withCredentials = true;

    $routeProvider
        .when('/', {
            templateUrl: 'views/main.html',
            controller: 'MainCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/dashboard', {
            templateUrl: 'views/dashboard.html',
            controller: 'DashboardCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/contact', {
            templateUrl: 'views/contact.html',
            controller: 'ContactCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/word-lookup', {
            templateUrl: 'views/word-lookup.html',
            controller: 'WordLookupCtrl',
            resolve: { user: mainApp.resolveUser }
        })

        .when('/word-lookup-quiz', {
            templateUrl: 'views/games/word-lookup-quiz.html',
            controller: 'WordLookupQuizCtrl',
            resolve: { user: mainApp.resolveUser }
        })
        .when('/word-game', {
            templateUrl: 'views/games/word-game.html',
            controller: 'WordLookupQuizOnlineCtrl',
            resolve: { user: mainApp.resolveUser }
        })

        .when('/login', {
            templateUrl: 'views/member/login.html',
            controller: 'LoginCtrl'
        })
        .when('/logout', {
            templateUrl: 'views/member/logout.html',
            controller: 'LogoutCtrl'
        })
        .when('/register', {
            templateUrl: 'views/member/register.html',
            controller: 'RegisterCtrl'
        })

        .when('/error/:type', {
            templateUrl: 'views/error.html',
            controller: 'ErrorCtrl'
        })

        .otherwise({
            redirectTo: '/'
        });
});

// EXTEND Classes here
mainApp.config(function ($routeProvider) {

    // check if dates are the same
    // it only checks: (day, month and year)
    Date.prototype.sameDateAs = function(pDate){
        return ((this.getFullYear()==pDate.getFullYear())&&(this.getMonth()==pDate.getMonth())&&(this.getDate()==pDate.getDate()));
    }

});

mainApp.run(function ($rootScope) {
    $rootScope.server = server;
});

mainApp.resolveUser = function($q, $route, $rootScope, $location, session){
    var defer = $q.defer();

    // if already have $rootScope.user, just return it
    if($rootScope.user){
        defer.resolve($rootScope.user)
    }

    // otherwise check if chrome storage has user session info
    else {
        session.check(function(user){
            // if it has, then return it
            if(user)
                defer.resolve(user);

            // otherwise, redirect to login
            else {
                defer.reject();
                $location.path('/login');
            }
        });
    }

    return defer.promise;
}

mainApp.filter('oneZeroToYesNo', function() {
    return function(input) {
        return input == 1 ? 'Yes' : 'No';
    };
});

mainApp.filter('oneZeroToSuccessFail', function() {
    return function(input) {
        return input == 1 ? 'Success' : 'Fail';
    };
});<|endoftext|>


<commit_before>export default [
    '(business|client|community|culture|customer|data|goal|intelligence|market' +
        '|process|quality|results|role|sales|subject|service|user)' +
        '.(centric(ity)?|facing|oriented|driven|focused|assessment|service|process)',
    '24/7',
    'ai',
    'agile',
    'artificial intelligence',
    'at (your|their) fingertips',
    'autonomous',
    'a[-/]b testing',
    'acquisition',
    'action items?',
    'act in time',
    'advantages?',
    'agents?',
    'aggregate',
    'accelerate',
    'all.in.one',
    'all.new',
    'analytics?',
    'application service providers?',
    'as a service',
    'assets?',
    'authoritative',
    'automated',
    'augmented',
    'extended reality',
    'award.winning',
    'b2(b|c)',
    'back to the drawing board',
    'ball.?park',
    'band.aid',
    'bandwidth',
    '(benefit|gap) analysis',
    'bespoke',
    'best.in.class',
    'best.of.breed',
    'best.practice',
    'big.data',
    'big picture',
    'big thinkers?',
    'block.?chain',
    'blazing(ly)? fast',
    'bottom.line',
    'bottom.up',
    'boost(s|ing)?',
    'brain.?storm(ing)?',
    'brain.?dump',
    'brand(s?|ing|ed)',
    'bright',
    'burn.rates?',
    'business( cases| plans)',
    'buzz',
    'call to action',
    'capacity',
    'capabilit(y|ies)',
    'capitali(s|z)e',
    'centers? of excellence',
    'challenges?',
    'change agents?',
    'circle the wagons',
    'client-centered',
    'client-centric',
    'client-focused',
    'cloud',
    'cloudify',
    'collaborat(e|ion|ive)s?',
    'committee',
    'communicat(e|ion)s?',
    'company-employee.fit',
    'compelling',
    'competitive( advantage)?',
    'connected systems?',
    'complex(ity)?',
    'comprehensive',
    'connect the dots',
    'containerizat(e|ion|ing)',
    'content management',
    'contextual(ly)?',
    'contingency plans?',
    'control groups?',
    'convergence',
    'convergent',
    'conversions?',
    'core business',
    'core competenc(y|ies)',
    'core.to.edge',
    'cost-effective',
    'cost/benefit',
    'cost control',
    'craftsmanship',
    'critical path',
    'crypto.currency',
    'crypto(?!graphy).\\w+',
    'crm',
    'cross.sell',
    'crowd.?(fund(s?|ed|ing)|sourc(ed|e|ing))',
    'customer obsession',
    'cutting.edge',
    'cyber',
    'dashboards?',
    'dashboarding',
    'data mining',
    'decentrali(s|z)ed',
    'de-?dupe',
    'deep dive',
    'deep learning',
    'delight',
    'deliverables?',
    'demographic',
    'demystify',
    'demystifying',
    'devops',
    'digital transformation',
    'discovery',
    'distributed ledgers?',
    'disrupt(ive)?',
    'dollar.productive',
    'downsi(s|z)e',
    'drill down',
    'drink the kool-aid',
    'drop.?in',
    'drop the ball',
    'due dilligence',
    'dynamic(s|ally)?',
    'e-?(business|commerce|tailers)',
    'eas(y|ily)',
    'ecosystems?',
    'efficien(t|cy)',
    'effortless(ly)?',
    'elastic',
    'elaboration',
    'elephant in the room',
    'elevator pitch',
    'enabl(e|ing)',
    'emerging markets?',
    'empower(ing|ment|s)?',
    'enablement',
    'end of the day',
    'end.to.end',
    'engulf',
    'engag(e|ing)',
    'enhanced?',
    'enterprise',
    'erp',
    'estimate',
    'eta',
    'etched in stone',
    'exceed expectations',
    'exclusive(ly)?',
    'exhaustive',
    'expedite',
    'experiences',
    'experts?',
    'expertise',
    'exposure',
    'extraordinary',
    'facilitat(e|or)',
    'fast track',
    'fault.tolerant',
    'first.to.market',
    'flexibility',
    'flux',
    'foot view',
    'four pillars',
    'front lines',
    'frustration[- ]free',
    'functional',
    'futurist',
    'full benefit',
    'future.proof',
    'game changer',
    'game plan',
    'behavioral',
    'global(ly)?',
    'go public',
    'go.to.market',
    'goals?',
    'going forward',
    'granular',
    'ground.?breaking',
    'growth',
    'grow',
    'guidance',
    'guru',
    'hackathon',
    'hacker( mindset)?',
    'happiness manage(ment|rs?)',
    'hardball',
    'heavy.lifting',
    'herding cats',
    'hidden.meaning',
    'high.level',
    '(high|mass).impact',
    'hive ?mind',
    'hybrid environments?',
    'hyperconverged',
    'holistic',
    'impactful',
    'impeccable',
    'in a nutshell',
    'incent',
    'incentivi(s|z)e',
    'increase the odds',
    'incredibl(e|y)',
    '(inflat|redeem)able value',
    'influencers?',
    'influx',
    'innovat(e|ed|ion|ive|ing|or)s?',
    'inspir(e|ing|ation)',
    'insights?',
    'integrat(e|ed|ion)s?',
    'internet of things',
    'intellectual property',
    'intuitive',
    'iot',
    'key results?',
    'kickstart(er|ed)?s?',
    'knowledge.(base|transfer|sharing)',
    'kpis?',
    'landing pages?',
    'lead the field',
    'leading',
    'leaders?',
    'leadership',
    'learnings',
    'legacy',
    'lessons learned',
    'level (the )? playing field',
    'level set',
    'leverag(e|ing)',
    'lifecycle',
    'low.hanging fruit',
    'look.(&|and).feel',
    'm2m',
    'machine learning',
    'made simple',
    'magical',
    'market (chang(er|ing)|leader|window)',
    'market.ready',
    'marketing collateral',
    'maximi(s|z)e',
    'meaningful( client | )interactions?',
    'measurements?',
    'methodolog(y|ies)',
    'metrics',
    'middleware',
    'milestone',
    'military.grade encryption',
    'mind ?share',
    'mind ?shower',
    'mind-boggling',
    'mindset',
    '(mission|time).critical',
    'ml',
    'moneti(s|z)e',
    'mov(e|ing) (fast|forward)',
    'multitask(ing?)',
    'multifaceted',
    'multi-?tenant(ed)?',
    'negotiated',
    'networking',
    'new.economy',
    'new.breed',
    '(new|next|second).(level|gen|generation)',
    'niches?',
    'ninja',
    'no-brainer',
    'non-traditional management',
    'objectives',
    'occupy the field',
    'off.site',
    'off.the.(radar|shelf)',
    'on board',
    'on.premises?',
    'on the (back end|radar screen|same page|house)',
    'one to one',
    'opportunit(y|ies)',
    'outperform',
    'optimal',
    'orthogonal',
    'outstanding',
    'out(side)?.of.the.(box|loop)',
    'outsourc(e|ed|ing)',
    '(total cost of )?ownership',
    'paradigms?( shift)?',
    'partner(ships?)?',
    'patents?',
    'performance indicators',
    'personaliz(e|ed|ation)',
    'perspective',
    'phases?',
    'phased approach',
    'pipeline',
    'pioneers',
    'pivot',
    'planning horizon',
    'platforms?',
    'plug.?in',
    'potentials?',
    'powerful',
    'prioriti(s|z)ed?',
    'proactive',
    'problem space',
    'processes',
    'profit(ability)?',
    'promotion',
    'promotional collateral',
    'prominent',
    'proprietary',
    'proof.of.concept',
    'purpose.built',
    'push the envelope',
    'push.back',
    'productivity',
    'pushing on open doors',
    'quick wins?',
    'rais(e|ing) the bar',
    'ramp.up',
    'relationship management',
    'responsive',
    'engage(ments?)?',
    'reach out',
    'reactivation',
    'real.time',
    'real.world',
    'reconfigure',
    'redefin(e|ed|ing)',
    'red flags?',
    'reengineering',
    'reinvent(ing)? the(.square)? wheel',
    'reinvigorate',
    'relevance',
    'repurpose',
    'resilien(ce|cy|t)',
    'resource allocation',
    'restructuring',
    'retention',
    'return on investment',
    'results',
    'reus(e|ability)',
    'revenue',
    'reverse.engineer',
    'revisit',
    'rich',
    'road ?map',
    'robust',
    'rock.?star',
    'roi',
    'run the numbers',
    '(s|p)aas',
    'sacrific(e|es|ing)',
    'scal(e|es|ing|ability)',
    'high availability',
    'scenarios?',
    'scope',
    'scrum( master)?',
    'seamless',
    'secret sauce',
    'search engine optimization',
    'segments?',
    'self-managed team',
    'seo',
    '(serial )?entrepreneurs?',
    'serverless',
    'shareholder value',
    'significant(ly)?',
    'single-source responsibility',
    'skill ?sets?',
    'smart(er)?',
    'smoke (&|and) mirrors',
    'social(.media|.gaming|.networks?)',
    'solutions?',
    'sophisticated',
    'soup to nuts',
    'sow',
    'stakeholders?',
    'start.up?',
    'statement of work',
    'state.of.the.art',
    'sticky-?ness',
    'strateg(y|ic|ize|ise)',
    'streamlin(ed|e|ing)',
    'story points?',
    'success(ful)?',
    'super(critical|star)',
    'sustainab(le|ility)',
    'synerg(y|ies|ized|i)',
    'systems?',
    'tailwinds?',
    'talented',
    'take offline',
    'talking points',
    'target (audience|group)',
    'targeted',
    'tasked',
    'tco',
    'team.building',
    'team.player',
    'teamwork',
    'technolog(y|ies)',
    'that being said',
    'throughput',
    'time.to.awesome',
    'time.to.market',
    'timelines?',
    'top.down',
    'top.of.the.game',
    'total quality',
    'touch.base',
    'touchpoints?',
    'traction',
    'transform',
    'trends?',
    'true',
    'truths?',
    'turnkey',
    'ultimate',
    'up.to.speed',
    'up-?sell',
    'upside',
    'user.friendly',
    'user funnels?',
    'user.experience',
    'utili(s|z)(e|ation)',
    'uncover',
    'unicorn',
    'unique approach',
    'unlimited.holidays',
    'values?',
    'valueable',
    'value.add(ed)?',
    'venture',
    'venturing',
    'vertical market',
    'viral',
    'virtual(ization|isation)?',
    'visibility',
    'vision',
    'walk the talk',
    'wearable',
    'web.enabled',
    'win-win',
    'wisdom of crowds',
    'with due respect',
    'with ease',
    'wizards?',
    'workflows?',
    'workloads?',
    'world.?class',
    'world a better place',
    'wow.factor',
    'you\'ve never seen (a|an) \\w+',
];
<commit_msg>add more bullshiting word (#118)<commit_after>export default [
    '(business|client|community|culture|customer|data|goal|intelligence|market' +
        '|process|quality|results|role|sales|subject|service|user)' +
        '.(centric(ity)?|facing|oriented|driven|focused|assessment|service|process)',
    '24/7',
    'ai',
    'agile',
    'artificial intelligence',
    'at (your|their) fingertips',
    'autonomous',
    'a[-/]b testing',
    'acquisition',
    'action items?',
    'act in time',
    'advantages?',
    'agents?',
    'aggregate',
    'accelerate',
    'all.in.one',
    'all.new',
    'analytics?',
    'application service providers?',
    'as a service',
    'assets?',
    'authoritative',
    'automated',
    'augmented',
    'extended reality',
    'award.winning',
    'b2(b|c)',
    'back to the drawing board',
    'ball.?park',
    'band.aid',
    'bandwidth',
    '(benefit|gap) analysis',
    'bespoke',
    'best.in.class',
    'best.of.breed',
    'best.practice',
    'big.data',
    'big picture',
    'big thinkers?',
    'block.?chain',
    'blazing(ly)? fast',
    'bottom.line',
    'bottom.up',
    'boost(s|ing)?',
    'brain.?storm(ing)?',
    'brain.?dump',
    'brand(s?|ing|ed)',
    'bright',
    'burn.rates?',
    'business( cases| plans)',
    'buzz',
    'call to action',
    'capacity',
    'capabilit(y|ies)',
    'capitali(s|z)e',
    'centers? of excellence',
    'challenges?',
    'change agents?',
    'circle the wagons',
    'client-centered',
    'client-centric',
    'client-focused',
    'cloud',
    'cloudify',
    'collaborat(e|ion|ive)s?',
    'committee',
    'communicat(e|ion)s?',
    'company-employee.fit',
    'compelling',
    'competitive( advantage)?',
    'connected systems?',
    'complex(ity)?',
    'comprehensive',
    'connect the dots',
    'containerizat(e|ion|ing)',
    'content management',
    'contextual(ly)?',
    'contingency plans?',
    'control groups?',
    'convergence',
    'convergent',
    'conversions?',
    'core business',
    'core competenc(y|ies)',
    'core.to.edge',
    'cost-effective',
    'cost/benefit',
    'cost control',
    'craftsmanship',
    'critical path',
    'crypto.currency',
    'crypto(?!graphy).\\w+',
    'crm',
    'cross.sell',
    'crowd.?(fund(s?|ed|ing)|sourc(ed|e|ing))',
    'customer obsession',
    'cutting.edge',
    'cyber',
    'dashboards?',
    'dashboarding',
    'data mining',
    'decentrali(s|z)ed',
    'de-?dupe',
    'deep dive',
    'deep learning',
    'delight',
    'deliverables?',
    'demographic',
    'demystify',
    'demystifying',
    'devops',
    'digital transformation',
    'discovery',
    'distributed ledgers?',
    'disrupt(ive|tor)?',
    'dollar.productive',
    'downsi(s|z)e',
    'drill down',
    'drink the kool-aid',
    'drop.?in',
    'drop the ball',
    'due dilligence',
    'dynamic(s|ally)?',
    'e-?(business|commerce|tailers)',
    'early.stage',
    'eas(y|ily)',
    'ecosystems?',
    'efficien(t|cy)',
    'effortless(ly)?',
    'elastic',
    'elaboration',
    'elephant in the room',
    'elevator pitch',
    'enabl(e|ing)',
    'emerging markets?',
    'empower(ing|ment|s)?',
    'enablement',
    'end of the day',
    'end.to.end',
    'engulf',
    'engag(e|ing)',
    'enhanced?',
    'enterprise',
    'erp',
    'estimate',
    'eta',
    'etched in stone',
    'evolution',
    'exceed expectations',
    'exclusive(ly)?',
    'exhaustive',
    'expedite',
    'experiences',
    'experts?',
    'expertise',
    'exposure',
    'extraordinary',
    'facilitat(e|or)',
    'fast track',
    'fault.tolerant',
    'first.to.market',
    'flexibility',
    'flux',
    'foot view',
    'forward-thinking',
    'four pillars',
    'frictionless',
    'front lines',
    'frustration[- ]free',
    'functional',
    'futurist',
    'full benefit',
    'future.proof',
    'game changer',
    'game plan',
    'behavioral',
    'global(ly)?',
    'go public',
    'go.to.market',
    'goals?',
    'going forward',
    'granular',
    'ground.?breaking',
    'growth',
    'grow',
    'guidance',
    'guru',
    'hackathon',
    'hacker( mindset)?',
    'happiness manage(ment|rs?)',
    'hardball',
    'heavy.lifting',
    'herding cats',
    'hidden.meaning',
    'high.level',
    '(high|mass).impact',
    'highly.scalable',
    'hive ?mind',
    'hybrid environments?',
    'hyper.personalization',
    'hyperconverged',
    'holistic',
    'impactful',
    'impeccable',
    'in a nutshell',
    'incent',
    'incentivi(s|z)e',
    'increase the odds',
    'incredibl(e|y)',
    '(inflat|redeem)able value',
    'influencers?',
    'influx',
    'innovat(e|ed|ion|ive|ing|or)s?',
    'inspir(e|ing|ation)',
    'insights?',
    'integrat(e|ed|ion)s?',
    'internet of things',
    'intellectual property',
    'intuitive',
    'iot',
    'key results?',
    'kickstart(er|ed)?s?',
    'knowledge.(base|transfer|sharing)',
    'kpis?',
    'landing pages?',
    'lead the field',
    'leading',
    'leaders?',
    'leadership',
    'learnings',
    'legacy',
    'lessons learned',
    'level (the )? playing field',
    'level set',
    'leverag(e|ing)',
    'lifecycle',
    'low.hanging fruit',
    'look.(&|and).feel',
    'm2m',
    'machine learning',
    'made simple',
    'magical',
    'market (chang(er|ing)|leader|window)',
    'market.ready',
    'marketing collateral',
    'maximi(s|z)e',
    'meaningful( client | )interactions?',
    'measurements?',
    'methodolog(y|ies)',
    'metrics',
    'middleware',
    'milestone',
    'military.grade encryption',
    'mind ?share',
    'mind ?shower',
    'mind-boggling',
    'mindset',
    '(mission|time).critical',
    'ml',
    'moneti(s|z)e',
    'mov(e|ing) (fast|forward)',
    'multitask(ing?)',
    'multifaceted',
    'multi-?tenant(ed)?',
    'negotiated',
    'networking',
    'new.economy',
    'new.breed',
    '(new|next|second).(level|gen|generation)',
    'niches?',
    'ninja',
    'no-brainer',
    'non-traditional management',
    'objectives',
    'occupy the field',
    'off.site',
    'off.the.(radar|shelf)',
    'on board',
    'on.premises?',
    'on the (back end|radar screen|same page|house)',
    'one to one',
    'opportunit(y|ies)',
    'outperform',
    'optimal',
    'orthogonal',
    'outstanding',
    'out(side)?.of.the.(box|loop)',
    'outsourc(e|ed|ing)',
    '(total cost of )?ownership',
    'paradigms?( shift)?',
    'partner(ships?)?',
    'patents?',
    'performance indicators',
    'personaliz(e|ed|ation)',
    'perspective',
    'phases?',
    'phased approach',
    'pipeline',
    'pioneers',
    'pivot',
    'planning horizon',
    'platforms?',
    'plug.?in',
    'potentials?',
    'powerful',
    'prioriti(s|z)ed?',
    'proactive',
    'problem space',
    'processes',
    'profit(ability)?',
    'promotion',
    'promotional collateral',
    'prominent',
    'proprietary',
    'proof.of.concept',
    'purpose.built',
    'push the envelope',
    'push.back',
    'production.ready',
    'productivity',
    'pushing on open doors',
    'quick wins?',
    'rais(e|ing) the bar',
    'ramp.up',
    'relationship management',
    'responsive',
    'engage(ments?)?',
    'reach out',
    'reactivation',
    'real.time',
    'real.world',
    'reconfigure',
    'redefin(e|ed|ing)',
    'red flags?',
    'reengineering',
    'reinvent(ing)? the(.square)? wheel',
    'reinvigorate',
    'relevance',
    'repurpose',
    'resilien(ce|cy|t)',
    'resource allocation',
    'restructuring',
    'retention',
    'return on investment',
    'results',
    'reus(e|ability)',
    'revenue',
    'reverse.engineer',
    'revisit',
    'revolution',
    'rich',
    'road ?map',
    'robust',
    'rock.?star',
    'roi',
    'run the numbers',
    '(s|p)aas',
    'sacrific(e|es|ing)',
    'scal(e|es|ing|ability)',
    'high availability',
    'scenarios?',
    'scope',
    'scrum( master)?',
    'seamless',
    'secret sauce',
    'search engine optimization',
    'segments?',
    'self-managed team',
    'seo',
    '(serial )?entrepreneurs?',
    'serverless',
    'shareholder value',
    'significant(ly)?',
    'single-source responsibility',
    'skill ?sets?',
    'smart(er)?',
    'smoke (&|and) mirrors',
    'social(.media|.gaming|.networks?)',
    'solidality',
    'solutions?',
    'sophisticated',
    'soup to nuts',
    'sow',
    'stakeholders?',
    'start.up?',
    'statement of work',
    'state.of.the.art',
    'sticky-?ness',
    'strateg(y|ic|ize|ise)',
    'streamlin(ed|e|ing)',
    'story points?',
    'success(ful)?',
    'super(critical|star)',
    'sustainab(le|ility)',
    'synerg(y|ies|ized|i)',
    'systems?',
    'tailwinds?',
    'talented',
    'take offline',
    'talking points',
    'target (audience|group)',
    'targeted',
    'tasked',
    'tco',
    'team.building',
    'team.player',
    'teamwork',
    'technolog(y|ies)',
    'that being said',
    'throughput',
    'time.to.awesome',
    'time.to.market',
    'timelines?',
    'top.down',
    'top.of.the.game',
    'total quality',
    'touch.base',
    'touchpoints?',
    'traction',
    'transfor(m|ming)',
    'trends?',
    'true',
    'truths?',
    'turnkey',
    'ultimate',
    'up.to.speed',
    'up-?sell',
    'upside',
    'user.friendly',
    'user funnels?',
    'user.experience',
    'utili(s|z)(e|ation)',
    'uncover',
    'unicorn',
    'unique approach',
    'unlimited.holidays',
    'values?',
    'valueable',
    'value.add(ed)?',
    'venture',
    'venturing',
    'vertical market',
    'viral',
    'virtual(ization|isation)?',
    'visibility',
    'visio(n|nary)',
    'walk the talk',
    'wearable',
    'web.enabled',
    'win-win',
    'wisdom of crowds',
    'with due respect',
    'with ease',
    'wizards?',
    'workflows?',
    'workloads?',
    'world.?class',
    'world a better place',
    'wow.factor',
    'you\'ve never seen (a|an) \\w+',
];
<|endoftext|>


<commit_before>var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');

// Sphinx theme nav state
function ThemeNav () {

    var nav = {
        navBar: null,
        win: null,
        winScroll: false,
        winResize: false,
        linkScroll: false,
        winPosition: 0,
        winHeight: null,
        docHeight: null,
        isRunning: false
    };

    nav.enable = function (withStickyNav) {
        var self = this;

        // TODO this can likely be removed once the theme javascript is broken
        // out from the RTD assets. This just ensures old projects that are
        // calling `enable()` get the sticky menu on by default. All other cals
        // to `enable` should include an argument for enabling the sticky menu.
        if (typeof(withStickyNav) == 'undefined') {
            withStickyNav = true;
        }

        if (self.isRunning) {
            // Only allow enabling nav logic once
            return;
        }

        self.isRunning = true;
        jQuery(function ($) {
            self.init($);

            self.reset();
            self.win.on('hashchange', self.reset);

            if (withStickyNav) {
                // Set scroll monitor
                self.win.on('scroll', function () {
                    if (!self.linkScroll) {
                        if (!self.winScroll) {
                            self.winScroll = true;
                            requestAnimationFrame(function() { self.onScroll(); });
                        }
                    }
                });
            }

            // Set resize monitor
            self.win.on('resize', function () {
                if (!self.winResize) {
                    self.winResize = true;
                    requestAnimationFrame(function() { self.onResize(); });
                }
            });

            self.onResize();
        });

    };

    // TODO remove this with a split in theme and Read the Docs JS logic as
    // well, it's only here to support 0.3.0 installs of our theme.
    nav.enableSticky = function() {
        this.enable(true);
    };

    nav.init = function ($) {
        var doc = $(document),
            self = this;

        this.navBar = $('div.wy-side-scroll:first');
        this.win = $(window);

        // Set up javascript UX bits
        $(document)
            // Shift nav in mobile when clicking the menu.
            .on('click', "[data-toggle='wy-nav-top']", function() {
                $("[data-toggle='wy-nav-shift']").toggleClass("shift");
                $("[data-toggle='rst-versions']").toggleClass("shift");
            })

            // Nav menu link click operations
            .on('click', ".wy-menu-vertical .current ul li a", function() {
                var target = $(this);
                // Close menu when you click a link.
                $("[data-toggle='wy-nav-shift']").removeClass("shift");
                $("[data-toggle='rst-versions']").toggleClass("shift");
                // Handle dynamic display of l3 and l4 nav lists
                self.toggleCurrent(target);
                self.hashChange();
            })
            .on('click', "[data-toggle='rst-current-version']", function() {
                $("[data-toggle='rst-versions']").toggleClass("shift-up");
            })

        // Make tables responsive
        $("table.docutils:not(.field-list,.footnote,.citation)")
            .wrap("

");

        // Add extra class to responsive tables that contain
        // footnotes or citations so that we can target them for styling
        $("table.docutils.footnote")
            .wrap("

");
        $("table.docutils.citation")
            .wrap("

");

        // Add expand links to all parents of nested ul
        $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
            var link = $(this);
                expand =
                    $('<button class="toctree-expand" title="Open/close menu"></button>');
            expand.on('click', function (ev) {
                self.toggleCurrent(link);
                ev.stopPropagation();
                return false;
            });
            link.prepend(expand);
        });
    };

    nav.reset = function () {
        // Get anchor from URL and open up nested nav
        var anchor = encodeURI(window.location.hash) || '#';

        try {
            var vmenu = $('.wy-menu-vertical');
            var link = vmenu.find('[href="' + anchor + '"]');
            if (link.length === 0) {
                // this link was not found in the sidebar.
                // Find associated id element, then its closest section
                // in the document and try with that one.
                var id_elt = $('.document [id="' + anchor.substring(1) + '"]');
                var closest_section = id_elt.closest('div.section');
                link = vmenu.find('[href="#' + closest_section.attr("id") + '"]');
                if (link.length === 0) {
                    // still not found in the sidebar. fall back to main section
                    link = vmenu.find('[href="#"]');
                }
            }
            // If we found a matching link then reset current and re-apply
            // otherwise retain the existing match
            if (link.length > 0) {
                $('.wy-menu-vertical .current').removeClass('current');
                link.addClass('current');
                link.closest('li.toctree-l1').parent().addClass('current');
                for (let i = 1; i <= 10; i++) {
                    link.closest('li.toctree-l' + i).addClass('current');
                }
                link[0].scrollIntoView();
            }
        }
        catch (err) {
            console.log("Error expanding nav for anchor", err);
        }

    };

    nav.onScroll = function () {
        this.winScroll = false;
        var newWinPosition = this.win.scrollTop(),
            winBottom = newWinPosition + this.winHeight,
            navPosition = this.navBar.scrollTop(),
            newNavPosition = navPosition + (newWinPosition - this.winPosition);
        if (newWinPosition < 0 || winBottom > this.docHeight) {
            return;
        }
        this.navBar.scrollTop(newNavPosition);
        this.winPosition = newWinPosition;
    };

    nav.onResize = function () {
        this.winResize = false;
        this.winHeight = this.win.height();
        this.docHeight = $(document).height();
    };

    nav.hashChange = function () {
        this.linkScroll = true;
        this.win.one('hashchange', function () {
            this.linkScroll = false;
        });
    };

    nav.toggleCurrent = function (elem) {
        var parent_li = elem.closest('li');
        parent_li.siblings('li.current').removeClass('current');
        parent_li.siblings().find('li.current').removeClass('current');
        var children = parent_li.find('> ul li');
        // Don't toggle terminal elements.
        if (children.length) {
            children.removeClass('current');
            parent_li.toggleClass('current');
        }
    }

    return nav;
};

module.exports.ThemeNav = ThemeNav();

if (typeof(window) != 'undefined') {
    window.SphinxRtdTheme = {
        Navigation: module.exports.ThemeNav,
        // TODO remove this once static assets are split up between the theme
        // and Read the Docs. For now, this patches 0.3.0 to be backwards
        // compatible with a pre-0.3.0 layout.html
        StickyNav: module.exports.ThemeNav,
    };
}

// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
// https://gist.github.com/paulirish/1579671
// MIT license

(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());
<commit_msg>Maintain aria-expanded along with .current in menu (#1151)<commit_after>var jQuery = (typeof(window) != 'undefined') ? window.jQuery : require('jquery');

// Sphinx theme nav state
function ThemeNav () {

    var nav = {
        navBar: null,
        win: null,
        winScroll: false,
        winResize: false,
        linkScroll: false,
        winPosition: 0,
        winHeight: null,
        docHeight: null,
        isRunning: false
    };

    nav.enable = function (withStickyNav) {
        var self = this;

        // TODO this can likely be removed once the theme javascript is broken
        // out from the RTD assets. This just ensures old projects that are
        // calling `enable()` get the sticky menu on by default. All other cals
        // to `enable` should include an argument for enabling the sticky menu.
        if (typeof(withStickyNav) == 'undefined') {
            withStickyNav = true;
        }

        if (self.isRunning) {
            // Only allow enabling nav logic once
            return;
        }

        self.isRunning = true;
        jQuery(function ($) {
            self.init($);

            self.reset();
            self.win.on('hashchange', self.reset);

            if (withStickyNav) {
                // Set scroll monitor
                self.win.on('scroll', function () {
                    if (!self.linkScroll) {
                        if (!self.winScroll) {
                            self.winScroll = true;
                            requestAnimationFrame(function() { self.onScroll(); });
                        }
                    }
                });
            }

            // Set resize monitor
            self.win.on('resize', function () {
                if (!self.winResize) {
                    self.winResize = true;
                    requestAnimationFrame(function() { self.onResize(); });
                }
            });

            self.onResize();
        });

    };

    // TODO remove this with a split in theme and Read the Docs JS logic as
    // well, it's only here to support 0.3.0 installs of our theme.
    nav.enableSticky = function() {
        this.enable(true);
    };

    nav.init = function ($) {
        var doc = $(document),
            self = this;

        this.navBar = $('div.wy-side-scroll:first');
        this.win = $(window);

        // Set up javascript UX bits
        $(document)
            // Shift nav in mobile when clicking the menu.
            .on('click', "[data-toggle='wy-nav-top']", function() {
                $("[data-toggle='wy-nav-shift']").toggleClass("shift");
                $("[data-toggle='rst-versions']").toggleClass("shift");
            })

            // Nav menu link click operations
            .on('click', ".wy-menu-vertical .current ul li a", function() {
                var target = $(this);
                // Close menu when you click a link.
                $("[data-toggle='wy-nav-shift']").removeClass("shift");
                $("[data-toggle='rst-versions']").toggleClass("shift");
                // Handle dynamic display of l3 and l4 nav lists
                self.toggleCurrent(target);
                self.hashChange();
            })
            .on('click', "[data-toggle='rst-current-version']", function() {
                $("[data-toggle='rst-versions']").toggleClass("shift-up");
            })

        // Make tables responsive
        $("table.docutils:not(.field-list,.footnote,.citation)")
            .wrap("

");

        // Add extra class to responsive tables that contain
        // footnotes or citations so that we can target them for styling
        $("table.docutils.footnote")
            .wrap("

");
        $("table.docutils.citation")
            .wrap("

");

        // Add expand links to all parents of nested ul
        $('.wy-menu-vertical ul').not('.simple').siblings('a').each(function () {
            var link = $(this);
                expand =
                    $('<button class="toctree-expand" title="Open/close menu"></button>');
            expand.on('click', function (ev) {
                self.toggleCurrent(link);
                ev.stopPropagation();
                return false;
            });
            link.prepend(expand);
        });
    };

    nav.reset = function () {
        // Get anchor from URL and open up nested nav
        var anchor = encodeURI(window.location.hash) || '#';

        try {
            var vmenu = $('.wy-menu-vertical');
            var link = vmenu.find('[href="' + anchor + '"]');
            if (link.length === 0) {
                // this link was not found in the sidebar.
                // Find associated id element, then its closest section
                // in the document and try with that one.
                var id_elt = $('.document [id="' + anchor.substring(1) + '"]');
                var closest_section = id_elt.closest('div.section');
                link = vmenu.find('[href="#' + closest_section.attr("id") + '"]');
                if (link.length === 0) {
                    // still not found in the sidebar. fall back to main section
                    link = vmenu.find('[href="#"]');
                }
            }
            // If we found a matching link then reset current and re-apply
            // otherwise retain the existing match
            if (link.length > 0) {
                $('.wy-menu-vertical .current')
                    .removeClass('current')
                    .attr('aria-expanded','false');
                link.addClass('current')
                    .attr('aria-expanded','true');
                link.closest('li.toctree-l1')
                    .parent()
                    .addClass('current')
                    .attr('aria-expanded','true');
                for (let i = 1; i <= 10; i++) {
                    link.closest('li.toctree-l' + i)
                        .addClass('current')
                        .attr('aria-expanded','true');
                }
                link[0].scrollIntoView();
            }
        }
        catch (err) {
            console.log("Error expanding nav for anchor", err);
        }

    };

    nav.onScroll = function () {
        this.winScroll = false;
        var newWinPosition = this.win.scrollTop(),
            winBottom = newWinPosition + this.winHeight,
            navPosition = this.navBar.scrollTop(),
            newNavPosition = navPosition + (newWinPosition - this.winPosition);
        if (newWinPosition < 0 || winBottom > this.docHeight) {
            return;
        }
        this.navBar.scrollTop(newNavPosition);
        this.winPosition = newWinPosition;
    };

    nav.onResize = function () {
        this.winResize = false;
        this.winHeight = this.win.height();
        this.docHeight = $(document).height();
    };

    nav.hashChange = function () {
        this.linkScroll = true;
        this.win.one('hashchange', function () {
            this.linkScroll = false;
        });
    };

    nav.toggleCurrent = function (elem) {
        var parent_li = elem.closest('li');
        parent_li
            .siblings('li.current')
            .removeClass('current')
            .attr('aria-expanded','false');
        parent_li
            .siblings()
            .find('li.current')
            .removeClass('current')
            .attr('aria-expanded','false');
        var children = parent_li.find('> ul li');
        // Don't toggle terminal elements.
        if (children.length) {
            children
                .removeClass('current')
                .attr('aria-expanded','false');
            parent_li
                .toggleClass('current')
                .attr('aria-expanded', function(i, old) {
                    return old == 'true' ? 'false' : 'true';
                });
        }
    }

    return nav;
};

module.exports.ThemeNav = ThemeNav();

if (typeof(window) != 'undefined') {
    window.SphinxRtdTheme = {
        Navigation: module.exports.ThemeNav,
        // TODO remove this once static assets are split up between the theme
        // and Read the Docs. For now, this patches 0.3.0 to be backwards
        // compatible with a pre-0.3.0 layout.html
        StickyNav: module.exports.ThemeNav,
    };
}

// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
// https://gist.github.com/paulirish/1579671
// MIT license

(function() {
    var lastTime = 0;
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());
<|endoftext|>


<commit_before>var Timer = function(interval) {
  this.interval = interval;
  this.eventHandlers = {};
  this.lastStart = 0;
};

Timer.prototype.on = function(event, handler) {
  var handlers = this.eventHandlers[event] || (this.eventHandlers[event] = []);
  handlers.push(handler);
};

Timer.prototype.fire = function(event) {
  var args = Array.prototype.slice.call(arguments, 1);
  if (this.eventHandlers[event]) {
    this.eventHandlers[event].forEach(function(cb) {
      cb.apply(null, args);
    });
  }
};

Timer.prototype.start = function() {
  if (this._intervalId) {
    throw new Error("Timer already started!");
  }

  var self = this;
  this.lastStart = Date.now();
  this._intervalId = setInterval(function() {
    self.fire('tick', Date.now() - self.lastStart);
  }, this.interval);
};

Timer.prototype.stop = function() {
  clearTimeout(this._intervalId);
  this._intervalId = null;
};

module.exports = Timer;
<commit_msg>timer yields delta, not cumulative<commit_after>var Timer = function(interval) {
  this.interval = interval;
  this.eventHandlers = {};
  this.lastStart = 0;
};

Timer.prototype.on = function(event, handler) {
  var handlers = this.eventHandlers[event] || (this.eventHandlers[event] = []);
  handlers.push(handler);
};

Timer.prototype.fire = function(event) {
  var args = Array.prototype.slice.call(arguments, 1);
  if (this.eventHandlers[event]) {
    this.eventHandlers[event].forEach(function(cb) {
      cb.apply(null, args);
    });
  }
};

Timer.prototype.start = function() {
  if (this._intervalId) {
    throw new Error("Timer already started!");
  }

  var self = this;
  this.lastTick = Date.now();
  this._intervalId = setInterval(function() {
    self.fire('tick', Date.now() - self.lastTick);
  }, this.interval);
};

Timer.prototype.stop = function() {
  clearTimeout(this._intervalId);
  this._intervalId = null;
};

module.exports = Timer;
<|endoftext|>


<commit_before>(function() {

    // Review/reply template.
    var reviewTemplate = getTemplate($('#review-template'));
    var reviewWithReply;

    z.page.on('fragmentloaded', function() {
        // Hijack <select> with stars.
        $('select[name="rating"]').ratingwidget();

        // Remove character counter on review field on mobile for now
        // (770661).
        if (!z.capabilities.mobile) {
            initCharCount();
        }

        // Show add review modal on app/app_slug/reviews/add for desktop.
        if ($('.reviews.add-review').length) {
            addOrEditYourReview($('#add-first-review'));
        }

        if (reviewWithReply && reviewWithReply.length) {
            var review = $('#' + reviewWithReply.attr('id'));
            review.siblings('.reply').show();
            $('html, body').scrollTo(review);
        }
    });

    // Returns the review body text or '' if the supplied element is not found.
    function getBody($body) {
        var body = $body.clone();
        // Get the inner *text* of the review body.
        body.find('.view-reply').remove();
        body.find('br').replaceWith('\n');
        // `.text()` returns the unescaped text content, so re-escape it.
        return body.text().trim()
                   .replace(/&/g,'&')
                   .replace(/</g,'<')
                   .replace(/>/g,'>');
    }

    function handleReviewOverlay(overlay) {
        // Stuff that is common to Edit and Reply.
        var $form = overlay.find('form');

        // Remove character counter on review field on mobile for now
        // (770661).
        if (!z.capabilities.mobile) {
            initCharCount(overlay);
        }

        overlay.addClass('show');

        overlay.on('submit', 'form', function(e) {
            overlay.removeClass('show');
            // Form submission is handled by POST hijacking.
        }).on('click', '.cancel', _pd(function() {
            overlay.removeClass('show');
        }));
    }

    function flagReview(reviewEl) {
        var overlay = makeOrGetOverlay('flag-review');
        overlay.addClass('show');
        overlay.one('click', '.cancel', _pd(function() {
            overlay.removeClass('show');
        })).one('click', '.menu a', _pd(function(e) {
            var flag = $(e.target).attr('href').slice(1),
                actionEl = reviewEl.find('.actions .flag');
            overlay.removeClass('show');
            actionEl.text(gettext('Sending report...'));
            $.post(
                reviewEl.data('flag-url'),
                {flag: flag}
            ).done(function() {
                actionEl.replaceWith(gettext('Flagged for review'));
            });
        }));
    }

    function deleteReview(reviewEl, action) {
        reviewEl.addClass('deleting');
        $.post(action);
        setTimeout(function() {
            reviewEl.addClass('deleted');
            if (reviewEl.hasClass('reply')) {
                var $parent = reviewEl.closest('.replies').prev('.review');
                // If this was a reply, remove the "1 reply" link.
                $parent.find('.view-reply').remove();
                $parent.find('ul.actions li.reply').removeClass('hidden');

                reviewEl.parent().remove();
            } else {
                // Change edit review button to submit review button.
                $('#add-edit-review').text(gettext('Write a Review'));
                $('#add-review').children().text(gettext('Write a Review'));
            }
            $('.notification.box').remove();

            // If already existing Django message, replace message.
            var success = $('.success h2');
            if (success.length) {
                success.text(gettext('Your review was successfully deleted!'));
            } else {
                $('#page').prepend($('
' +
                    '

' +
                    gettext('Your review was successfully deleted!') +
                    '

'));
            }
        }, 500);
    }

    // Edit review on the review listing page.
    function editReview(reviewEl) {
        var overlay = makeOrGetOverlay('edit-review'),
            rating = reviewEl.data('rating'),
            action = reviewEl.closest('[data-edit-url]').data('edit-url'),
            body = getBody(reviewEl.find('.body'));
        overlay.html(reviewTemplate({title: gettext('Edit Review'),
                                     action: action, body: body}));
        if (reviewEl.hasClass('reply')) {
            overlay.find('select[name="rating"]').remove();
        } else {
            if (z.body.hasClass('desktop')) {
                overlay.find('select[name="rating"]').ratingwidget('large');
            } else {
                overlay.find('select[name="rating"]').ratingwidget();
            }
            overlay.find(format('.ratingwidget [value="{0}"]', rating)).click();
        }
        handleReviewOverlay(overlay);
    }

    // This gets used when you're not editing a review on the review list page.
    function addOrEditYourReview($senderEl) {
        var overlay = makeOrGetOverlay('edit-review'),
            rating = $senderEl.data('rating'),
            title = gettext('Write a Review'),
            body = getBody($('#current-review')),
            action = $senderEl.data('href');

        if (rating > 0) {
            title = gettext('Edit Your Review');
        }

        overlay.html(reviewTemplate({title: title, action: action,
                                     body: body}));

        overlay.find('select[name="rating"]').ratingwidget('large');
        overlay.find(format('.ratingwidget [value="{0}"]', rating)).click();
        handleReviewOverlay(overlay);
    }

    function replyReview(reviewEl, action, isNewReview) {
        var overlay = makeOrGetOverlay('edit-review'),
            title = gettext('Reply Review'),
            body = '';

        if (!isNewReview) {
            title = gettext('Edit Reply');
            body = getBody(reviewEl.find('.body'));
        }

        overlay.html(reviewTemplate({title: title, action: action,
                                     body: body}));
        overlay.addClass('reply');
        handleReviewOverlay(overlay);
    }

    // Toggle rating breakdown (on listing page only, not detail page).
    z.page.on('click', '.average-rating-listing', _pd(function() {
        $('.grouped-ratings').toggle();
    })).on('click', '.grouped-ratings-listing', _pd(function() {
        $('.grouped-ratings').hide();
    }));

    // Cancel rating button.
    z.page.on('click', '.submit-review .cancel', _pd(nav.back));

    z.page.on('click', '.review .actions a, #add-first-review[data-href]', _pd(function(e) {
        var $this = $(this),
            action = $this.data('action');
        if (!action) return;
        var $review = $this.closest('.review');
        switch (action) {
            case 'delete':
                deleteReview($review, $this.attr('href'));
                break;
            case 'edit':
                editReview($review);
                break;
            case 'add-or-edit':
                addOrEditYourReview($this);
                break;
            case 'report':
                flagReview($review);
                break;
            case 'reply':
                replyReview($review, $this.attr('href'), true);
                break;
            case 'edit-reply':
                replyReview($review, $this.attr('href'));
                break;
        }
    }));

    // View reply.
    z.page.on('click', '.review .view-reply', _pd(function() {
        $(this).closest('.review').next('.replies').find('.reply').toggle();
    }));
})();
<commit_msg>Always use the char counter again ('revert this when krupa complains' -@cvan)<commit_after>(function() {

    // Review/reply template.
    var reviewTemplate = getTemplate($('#review-template'));
    var reviewWithReply;

    var alwaysUseCharCounter = true;

    z.page.on('fragmentloaded', function() {
        // Hijack <select> with stars.
        $('select[name="rating"]').ratingwidget();

        // Remove character counter on review field on mobile for now
        // (770661).
        if (alwaysUseCharCounter || !z.capabilities.mobile) {
            initCharCount();
        }

        // Show add review modal on app/app_slug/reviews/add for desktop.
        if ($('.reviews.add-review').length) {
            addOrEditYourReview($('#add-first-review'));
        }

        if (reviewWithReply && reviewWithReply.length) {
            var review = $('#' + reviewWithReply.attr('id'));
            review.siblings('.reply').show();
            $('html, body').scrollTo(review);
        }
    });

    // Returns the review body text or '' if the supplied element is not found.
    function getBody($body) {
        var body = $body.clone();
        // Get the inner *text* of the review body.
        body.find('.view-reply').remove();
        body.find('br').replaceWith('\n');
        // `.text()` returns the unescaped text content, so re-escape it.
        return body.text().trim()
                   .replace(/&/g,'&')
                   .replace(/</g,'<')
                   .replace(/>/g,'>');
    }

    function handleReviewOverlay(overlay) {
        // Stuff that is common to Edit and Reply.
        var $form = overlay.find('form');

        // Remove character counter on review field on mobile for now
        // (770661).
        if (alwaysUseCharCounter || !z.capabilities.mobile) {
            initCharCount(overlay);
        }

        overlay.addClass('show');

        overlay.on('submit', 'form', function(e) {
            overlay.removeClass('show');
            // Form submission is handled by POST hijacking.
        }).on('click', '.cancel', _pd(function() {
            overlay.removeClass('show');
        }));
    }

    function flagReview(reviewEl) {
        var overlay = makeOrGetOverlay('flag-review');
        overlay.addClass('show');
        overlay.one('click', '.cancel', _pd(function() {
            overlay.removeClass('show');
        })).one('click', '.menu a', _pd(function(e) {
            var flag = $(e.target).attr('href').slice(1),
                actionEl = reviewEl.find('.actions .flag');
            overlay.removeClass('show');
            actionEl.text(gettext('Sending report...'));
            $.post(
                reviewEl.data('flag-url'),
                {flag: flag}
            ).done(function() {
                actionEl.replaceWith(gettext('Flagged for review'));
            });
        }));
    }

    function deleteReview(reviewEl, action) {
        reviewEl.addClass('deleting');
        $.post(action);
        setTimeout(function() {
            reviewEl.addClass('deleted');
            if (reviewEl.hasClass('reply')) {
                var $parent = reviewEl.closest('.replies').prev('.review');
                // If this was a reply, remove the "1 reply" link.
                $parent.find('.view-reply').remove();
                $parent.find('ul.actions li.reply').removeClass('hidden');

                reviewEl.parent().remove();
            } else {
                // Change edit review button to submit review button.
                $('#add-edit-review').text(gettext('Write a Review'));
                $('#add-review').children().text(gettext('Write a Review'));
            }
            $('.notification.box').remove();

            // If already existing Django message, replace message.
            var success = $('.success h2');
            if (success.length) {
                success.text(gettext('Your review was successfully deleted!'));
            } else {
                $('#page').prepend($('
' +
                    '

' +
                    gettext('Your review was successfully deleted!') +
                    '

'));
            }
        }, 500);
    }

    // Edit review on the review listing page.
    function editReview(reviewEl) {
        var overlay = makeOrGetOverlay('edit-review'),
            rating = reviewEl.data('rating'),
            action = reviewEl.closest('[data-edit-url]').data('edit-url'),
            body = getBody(reviewEl.find('.body'));
        overlay.html(reviewTemplate({title: gettext('Edit Review'),
                                     action: action, body: body}));
        if (reviewEl.hasClass('reply')) {
            overlay.find('select[name="rating"]').remove();
        } else {
            if (z.body.hasClass('desktop')) {
                overlay.find('select[name="rating"]').ratingwidget('large');
            } else {
                overlay.find('select[name="rating"]').ratingwidget();
            }
            overlay.find(format('.ratingwidget [value="{0}"]', rating)).click();
        }
        handleReviewOverlay(overlay);
    }

    // This gets used when you're not editing a review on the review list page.
    function addOrEditYourReview($senderEl) {
        var overlay = makeOrGetOverlay('edit-review'),
            rating = $senderEl.data('rating'),
            title = gettext('Write a Review'),
            body = getBody($('#current-review')),
            action = $senderEl.data('href');

        if (rating > 0) {
            title = gettext('Edit Your Review');
        }

        overlay.html(reviewTemplate({title: title, action: action,
                                     body: body}));

        overlay.find('select[name="rating"]').ratingwidget('large');
        overlay.find(format('.ratingwidget [value="{0}"]', rating)).click();
        handleReviewOverlay(overlay);
    }

    function replyReview(reviewEl, action, isNewReview) {
        var overlay = makeOrGetOverlay('edit-review'),
            title = gettext('Reply Review'),
            body = '';

        if (!isNewReview) {
            title = gettext('Edit Reply');
            body = getBody(reviewEl.find('.body'));
        }

        overlay.html(reviewTemplate({title: title, action: action,
                                     body: body}));
        overlay.addClass('reply');
        handleReviewOverlay(overlay);
    }

    // Toggle rating breakdown (on listing page only, not detail page).
    z.page.on('click', '.average-rating-listing', _pd(function() {
        $('.grouped-ratings').toggle();
    })).on('click', '.grouped-ratings-listing', _pd(function() {
        $('.grouped-ratings').hide();
    }));

    // Cancel rating button.
    z.page.on('click', '.submit-review .cancel', _pd(nav.back));

    z.page.on('click', '.review .actions a, #add-first-review[data-href]', _pd(function(e) {
        var $this = $(this),
            action = $this.data('action');
        if (!action) return;
        var $review = $this.closest('.review');
        switch (action) {
            case 'delete':
                deleteReview($review, $this.attr('href'));
                break;
            case 'edit':
                editReview($review);
                break;
            case 'add-or-edit':
                addOrEditYourReview($this);
                break;
            case 'report':
                flagReview($review);
                break;
            case 'reply':
                replyReview($review, $this.attr('href'), true);
                break;
            case 'edit-reply':
                replyReview($review, $this.attr('href'));
                break;
        }
    }));

    // View reply.
    z.page.on('click', '.review .view-reply', _pd(function() {
        $(this).closest('.review').next('.replies').find('.reply').toggle();
    }));
})();
<|endoftext|>


<commit_before>import { Color, pt } from "lively.graphics";
import { morph } from "lively.morphic";

export var migrations = [

  {
    date: "2017-04-08",
    name: "Text and Label textAndAttributes format change",
    description: `
Changing the format from
  [[string1, attr1_1, attr1_2], [string2, attr2_1, attr2_2], ...]
to
  [string1, attr1, string2, attr2, ...].
    `,
    snapshotConverter: idAndSnapshot => {
      let {snapshot} = idAndSnapshot;
      for (let key in snapshot) {
        let serialized = snapshot[key],
            textAndAttributes = serialized.props && serialized.props.textAndAttributes;
        if (!textAndAttributes) continue;
        let {value} = textAndAttributes;
        if (!Array.isArray(value)) {
          console.warn(`object migrator found textAndAttributes field but it is not an Array!`);
          continue;
        }
        if (!value.length || typeof value[0] === "string") continue; // OK
        // flatten values
        value = [].concat.apply([], value);
        for (let i = 0; i < value.length; i += 2) {
          let text = value[i], attr = value[i+1];
          if (attr && Array.isArray(attr)) // merge multi-attributes
            value[i+1] = Object.assign({}, ...attr);
        }
        serialized.props.textAndAttributes = {...textAndAttributes, value};
      }
      return idAndSnapshot;
    }
  },

  {
    date: "2017-04-29",
    name: "Window button fix",
    description: `
A recent change in the structure of windows, that now adds a "button wrapper"
morph breaks old windows without it.
`,
    objectConverter: ({snapshot, id}, pool) => {
      let rootMorph = pool.refForId(id).realObj;
      if (rootMorph && rootMorph.isMorph)
        rootMorph.withAllSubmorphsDo(win => {
          if (!win.isWindow || win.submorphs.some(m => m.name === "button wrapper")) return;

          let btnWrapper = morph({
            name: "button wrapper",
            styleClasses: ["buttonGroup"],
            submorphs: win.buttons()
          });
          win.controls = [btnWrapper, win.titleLabel()];
          if (win.resizable) win.controls.push(win.resizer());
          win.submorphs = [...win.submorphs, ...win.controls];
          btnWrapper.position = pt(0,0)
          win.buttons().forEach(ea => ea.extent = pt(14,14));
          win.getWindow().relayoutWindowControls();
        });
    }
  }

];<commit_msg>serialization: migration for ide changes (theme, js highlighter removal)<commit_after>import { Color, pt } from "lively.graphics";
import { morph } from "lively.morphic";

export var migrations = [

  {
    date: "2017-04-08",
    name: "Text and Label textAndAttributes format change",
    description: `
Changing the format from
  [[string1, attr1_1, attr1_2], [string2, attr2_1, attr2_2], ...]
to
  [string1, attr1, string2, attr2, ...].
    `,
    snapshotConverter: idAndSnapshot => {
      let {snapshot} = idAndSnapshot;
      for (let key in snapshot) {
        let serialized = snapshot[key],
            textAndAttributes = serialized.props && serialized.props.textAndAttributes;
        if (!textAndAttributes) continue;
        let {value} = textAndAttributes;
        if (!Array.isArray(value)) {
          console.warn(`object migrator found textAndAttributes field but it is not an Array!`);
          continue;
        }
        if (!value.length || typeof value[0] === "string") continue; // OK
        // flatten values
        value = [].concat.apply([], value);
        for (let i = 0; i < value.length; i += 2) {
          let text = value[i], attr = value[i+1];
          if (attr && Array.isArray(attr)) // merge multi-attributes
            value[i+1] = Object.assign({}, ...attr);
        }
        serialized.props.textAndAttributes = {...textAndAttributes, value};
      }
      return idAndSnapshot;
    }
  },

  {
    date: "2017-04-29",
    name: "Window button fix",
    description: `
A recent change in the structure of windows, that now adds a "button wrapper"
morph breaks old windows without it.
`,
    objectConverter: ({snapshot, id}, pool) => {
      let rootMorph = pool.refForId(id).realObj;
      if (rootMorph && rootMorph.isMorph)
        rootMorph.withAllSubmorphsDo(win => {
          if (!win.isWindow || win.submorphs.some(m => m.name === "button wrapper")) return;

          let btnWrapper = morph({
            name: "button wrapper",
            styleClasses: ["buttonGroup"],
            submorphs: win.buttons()
          });
          win.controls = [btnWrapper, win.titleLabel()];
          if (win.resizable) win.controls.push(win.resizer());
          win.submorphs = [...win.submorphs, ...win.controls];
          btnWrapper.position = pt(0,0)
          win.buttons().forEach(ea => ea.extent = pt(14,14));
          win.getWindow().relayoutWindowControls();
        });
    }
  },

  {
    date: "2017-05-22",
    name: "Removal of ChromeTheme and GithubTheme",
    description: `
For now only a simple default theme...
`,
    snapshotConverter: idAndSnapshot => {
      let {snapshot} = idAndSnapshot;
      for (let key in snapshot) {
        let serialized = snapshot[key],
            klass = serialized["lively.serializer-class-info"];
        if (!klass) continue;
        if (klass.className === "ChromeTheme" || klass.className === "GithubTheme") {
          klass.className = "DefaultTheme";
          klass.module.pathInPackage = "ide/themes/default.js";
        } else if (klass.className === "JavaScriptTokenizer") {
          delete serialized["lively.serializer-class-info"]
        }
      }
      return idAndSnapshot;
    }
  }

];<|endoftext|>


<commit_before>module.exports = DefaultCollection;

function DefaultCollection() {}

DefaultCollection.prototype.query = function () {
  var args = Array.prototype.slice.call(arguments);
  args = [this._at].concat(args);

  return this.root.query.apply(this.root, args);
};

DefaultCollection.prototype.subscribe = function () {
  var args = Array.prototype.slice.call(arguments);

  this._fetchSubscribe('subscribe', args);
};

DefaultCollection.prototype.fetch = function () {
  var args = Array.prototype.slice.call(arguments);

  this._fetchSubscribe('fetch', args);
};

DefaultCollection.prototype._fetchSubscribe = function (method, args) {
  // No args passed, just pass along as scoped
  if(!args.length) return this[method]();

  // A cb was the only argument passed, just pass along as scoped
  if(typeof args[0] === 'function') return this[method].apply(this, args);

  // A path (i.e. a string) was passed as the first arg - just pass long as scoped
  if(typeof args[0] === 'string') return this[method].apply(this, args);

  // A query was passed along, we need to go to root
  return this.root[method].apply(this, args);
};
<commit_msg>Fix issue with subscriptions/fetches<commit_after>module.exports = DefaultCollection;

function DefaultCollection() {}

DefaultCollection.prototype.query = function () {
  var args = Array.prototype.slice.call(arguments);
  args = [this._at].concat(args);

  return this.root.query.apply(this.root, args);
};

DefaultCollection.prototype.subscribe = function () {
  var args = Array.prototype.slice.call(arguments);

  this._fetchSubscribe('subscribe', args);
};

DefaultCollection.prototype.fetch = function () {
  var args = Array.prototype.slice.call(arguments);

  this._fetchSubscribe('fetch', args);
};

DefaultCollection.prototype._fetchSubscribe = function (method, args) {
  // No args passed, just pass along as scoped
  if(!args.length) return this.root[method].apply(this);;

  // A cb was the only argument passed, just pass along as scoped
  if(typeof args[0] === 'function') return this.root[method].apply(this, args);

  // A path (i.e. a string) was passed as the first arg - just pass long as scoped
  if(typeof args[0] === 'string') return this.root[method].apply(this, args);

  // A query was passed along, we need to go to root
  return this.root[method].apply(this, args);
};
<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Authors Simen Brekken @simenbrekken, Einar Löve @einarlove
*/

"use strict";

const DefinePlugin = require("./DefinePlugin");
const WebpackError = require("./WebpackError");

/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./DefinePlugin").CodeValue} CodeValue */

class EnvironmentPlugin {
	constructor(...keys) {
		if (keys.length === 1 && Array.isArray(keys[0])) {
			this.keys = keys[0];
			this.defaultValues = {};
		} else if (keys.length === 1 && keys[0] && typeof keys[0] === "object") {
			this.keys = Object.keys(keys[0]);
			this.defaultValues = keys[0];
		} else {
			this.keys = keys;
			this.defaultValues = {};
		}
	}

	/**
	 * @param {Compiler} compiler webpack compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		/** @type {Record<string, CodeValue>} */
		const definitions = {};
		for (const key of this.keys) {
			const value =
				process.env[key] !== undefined
					? process.env[key]
					: this.defaultValues[key];

			if (value === undefined) {
				compiler.hooks.thisCompilation.tap("EnvironmentPlugin", compilation => {
					const error = new WebpackError(
						`EnvironmentPlugin - ${key} environment variable is undefined.\n\n` +
							"You can pass an object with default values to suppress this warning.\n" +
							"See https://webpack.js.org/plugins/environment-plugin for example."
					);

					error.name = "EnvVariableNotDefinedError";
					compilation.warnings.push(error);
				});
			}

			definitions[`process.env.${key}`] =
				value === undefined ? "undefined" : JSON.stringify(value);
		}

		new DefinePlugin(definitions).apply(compiler);
	}
}

module.exports = EnvironmentPlugin;
<commit_msg>Add options arg to EnvironmentPlugin, fixes #10296<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Authors Simen Brekken @simenbrekken, Einar Löve @einarlove
*/

"use strict";

const DefinePlugin = require("./DefinePlugin");
const WebpackError = require("./WebpackError");

/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./DefinePlugin").CodeValue} CodeValue */

class EnvironmentPlugin {
	constructor(...keys) {
		this.options = {};
		if (keys.length > 1) {
			const options = keys[keys.length - 1];
			if (typeof options === "object") {
				this.options = options;
				// remove options object from env keys
				keys.pop();
			}
		}

		if (keys.length === 1 && Array.isArray(keys[0])) {
			this.keys = keys[0];
			this.defaultValues = {};
		} else if (keys.length === 1 && keys[0] && typeof keys[0] === "object") {
			this.keys = Object.keys(keys[0]);
			this.defaultValues = keys[0];
		} else {
			this.keys = keys;
			this.defaultValues = {};
		}
	}

	/**
	 * @param {Compiler} compiler webpack compiler instance
	 * @returns {void}
	 */
	apply(compiler) {
		/** @type {Record<string, CodeValue>} */
		const definitions = {};
		for (const key of this.keys) {
			const value =
				process.env[key] !== undefined
					? process.env[key]
					: this.defaultValues[key];

			if (value === undefined) {
				compiler.hooks.thisCompilation.tap("EnvironmentPlugin", compilation => {
					const error = new WebpackError(
						`EnvironmentPlugin - ${key} environment variable is undefined.\n\n` +
							"You can pass an object with default values to suppress this warning.\n" +
							"See https://webpack.js.org/plugins/environment-plugin for example."
					);

					error.name = "EnvVariableNotDefinedError";
					if (this.options["errorLevel"] === "error") {
						compilation.errors.push(error);
					} else {
						compilation.warnings.push(error);
					}
				});
			}

			definitions[`process.env.${key}`] =
				value === undefined ? "undefined" : JSON.stringify(value);
		}

		new DefinePlugin(definitions).apply(compiler);
	}
}

module.exports = EnvironmentPlugin;
<|endoftext|>