<commit_before>var __utils  = require('./lib/utils.js'),
    __token  = require('./lib/token.js'),
    __cookie = require('./lib/cookie.js')

module.exports = function () {

    // Private (used double underscore __).

    function __duckPunch(methodName, data) {
        var _this = this,
            success = data.success;

        data = __utils.extend(this.options[methodName + 'Data'], [data]);

        data.success = function (res) {
            data.success = success;

            _this.options[methodName + 'Process'].call(_this, res, data);
        };

        this.options.http._http.call(this, data);
    }

    function __bindContext(methodName, data) {
        var _auth = this.$auth;

        _auth.options[methodName + 'Perform'].call(_auth, _auth.options.router._bindData.call(_auth, data, this));
    }

    // Overrideable

    function _routerBeforeEach(cb) {

        if (this.options.tokenExpired.call(this)) {
            this.options.refreshPerform.call(this, {});
        }

        if (this.watch.authenticated === null && __token.get.call(this)) {
            if ( ! __cookie.exists.call(this)) {
                this.options.logoutProcess.call(this, null, {});

                this.watch.loaded = true

                return cb.call(this);
            }

            this.watch.authenticated = false
            this.options.fetchPerform.call(this, {success: cb, error: cb});
        } else {
            this.watch.loaded = true;
            return cb.call(this);
        }
    }

    function _transitionEach(routeAuth, cb) {
        routeAuth = __utils.toArray(routeAuth);

        if (routeAuth && (routeAuth === true || routeAuth.constructor === Array)) {
            if ( ! this.check()) {
                cb.call(this, this.options.authRedirect);
            }
            else if (routeAuth.constructor === Array && ! __utils.compare(routeAuth, this.watch.data[this.options.rolesVar])) {
                cb.call(this, this.options.forbiddenRedirect);
            }
            else {
                return cb();
            }
        }
        else if (routeAuth === false && this.check()) {
            cb.call(this, this.options.notFoundRedirect);
        }
        else {
            return cb();
        }
    }

    function _requestIntercept(req) {
        var token = __token.get.call(this);

        if (token) {
            this.options.auth.request.call(this, req, token);
        }

        return req;
    }

    function _responseIntercept(res) {
        var token;

        if (this.options.http._invalidToken) {
            this.options.http._invalidToken.call(this, res);
        }

        token = this.options.auth.response.call(this, res);

        if (token) {
            __token.set.call(this, null, token);
        }
    }

    function _parseUserData(data) {
        return data.data;
    }

    function _check(role) {
        if (this.watch.authenticated === true) {
            if (role) {
                return __utils.compare(role, this.watch.data[this.options.rolesVar]);
            }

            return true;
        }

        return false;
    }

    function _tokenExpired () {
        return ! this.watch.loaded && __token.get.call(this);
    }

    function _cookieDomain () {
        return window.location.hostname;
    }

    function _getUrl () {
        var port = window.location.port

        return window.location.protocol + '//' + window.location.hostname + (port ? ':' + port : '')
    }

    function _fetchPerform(data) {
        var _this = this,
            error = data.error;

        data.error = function (res) {
            _this.watch.loaded = true;

            if (error) { error.call(_this, res); }
        };

        __duckPunch.call(this, 'fetch', data);
    }

    function _fetchProcess(res, data) {
        this.watch.authenticated = true;
        this.watch.data = this.options.parseUserData.call(this, this.options.http._httpData.call(this, res));
        this.watch.loaded = true;

        if (data.success) { data.success.call(this, res); }
    }

    function _refreshPerform(data) {
        __duckPunch.call(this, 'refresh', data);
    }

    function _refreshProcess(res, data) {
        if (data.success) { data.success.call(this, res); }
    }

    function _registerPerform(data) {
        __duckPunch.call(this, 'register', data);
    }

    function _registerProcess(res, data) {
        if (data.autoLogin === true) {
            data = __utils.extend(data, [this.options.loginData]);

            this.options.loginPerform.call(this, data);
        }
        else {
            if (data.success) { data.success.call(this, res); }

            if (data.redirect) {
                this.options.router._routerGo.call(this, data.redirect);
            }
        }
    }

    function _loginPerform(data) {
        __duckPunch.call(this, 'login', data);
    }

    function _loginProcess(res, data) {
        var _this = this;

        __cookie.set.call(this, data.rememberMe);

        this.authenticated = null;

        this.options.fetchPerform.call(this, {
            success: function () {
                if (data.success) { data.success.call(this, res); }

                if (data.redirect && _this.options.check.call(_this)) {
                    _this.options.router._routerGo.call(_this, data.redirect);
                }
            }
        });
    }

    function _logoutPerform(data) {
        data = __utils.extend(this.options.logoutData, [data || {}]);

        if (data.makeRequest) {
            __duckPunch.call(this, 'logout', data);
        }
        else {
            this.options.logoutProcess.call(this, null, data);
        }
    }

    function _logoutProcess(res, data) {
        __cookie.delete.call(this);

        __token.delete.call(this, 'other');
        __token.delete.call(this, 'default');

        this.authenticated = false;
        this.watch.data = null;

        if (data.success) { data.success.call(this, res, data); }

        if (data.redirect) {
            this.options.router._routerGo.call(this, data.redirect);
        }
    }

    function _loginOtherPerform(data) {
        var success,
            token = this.token.call(this); // (admin) token

        data = data || {};

        success = data.success;

        data.success = function () {

            // Reshuffle tokens here...
            __token.set.call(this, 'other', this.token.call(this));
            __token.set.call(this, 'default', token);

            if (success) { success.call(this); }
        };

        __duckPunch.call(this, 'loginOther', data);
    }

    function _loginOtherProcess(res, data) {
        var _this = this;

        this.options.fetchPerform.call(this, {
            success: function () {
                if (data.success) { data.success.call(this, res); }

                if (data.redirect && _this.options.check.call(_this)) {
                    _this.options.router._routerGo.call(_this, data.redirect);
                }
            }
        });
    }

    function _logoutOtherPerform(data) {
        data = __utils.extend(this.options.logoutOtherData, [data || {}]);

        if (data.makeRequest) {
            __duckPunch.call(this, 'logoutOther', data);
        }
        else {
            this.options.logoutOtherProcess.call(this, null, data);
        }
    }

    function _logoutOtherProcess(res, data) {
        __token.delete.call(this, 'other');

        this.options.fetchPerform.call(this, {
            success: function () {
                if (data.success) { data.success.call(this, res, data); }

                if (data.redirect) {
                    this.options.router._routerGo.call(this, data.redirect);
                }
            }
        });
    }

    function _oauth2Perform(data) {
        var state = {},
            params = '',
            query = {};

        if (data.code === true) {
            data = __utils.extend(this.options[data.provider + 'Data'], [data]);

            try {
                if (data.query.state) {
                    state = JSON.parse(decodeURIComponent(data.query.state));
                }
            }
            catch (e) {
                console.error('vue-auth:error There was an issue retrieving the state data.');
                state = {};
            }

            data.rememberMe = state.rememberMe === true;
            data.state = state;

            this.options.loginPerform.call(this, data);
        } else {
            data = __utils.extend(this.options[data.provider + 'Oauth2Data'], [data]);

            data.redirect = data.redirect.call(this);

            data.state = data.state || {};
            data.state.rememberMe = data.rememberMe === true;

            params = '?client_id=' + data.clientId + '&redirect_uri=' + data.redirect + '&scope=' + data.scope + '&response_type=code&state=' + encodeURIComponent(JSON.stringify(data.state));

            window.location = data.url + params;
        }
    }

    var defaultOptions = {

        // Variables

        rolesVar:          'roles',
        tokenName:         'auth-token',

        // Objects

        authRedirect:       {path: '/login'},
        forbiddenRedirect:  {path: '/403'},
        notFoundRedirect:   {path: '/404'},

        registerData:       {url: 'auth/register',     method: 'POST', redirect: '/login'},
        loginData:          {url: 'auth/login',        method: 'POST', redirect: '/'},
        logoutData:         {url: 'auth/logout',       method: 'POST', redirect: '/', makeRequest: false},
        oauth1Data:         {url: 'auth/login',        method: 'POST'},
        fetchData:          {url: 'auth/user',         method: 'GET'},
        refreshData:        {url: 'auth/refresh',      method: 'GET'},
        loginOtherData:     {url: 'auth/login-other',  method: 'POST', redirect: '/'},
        logoutOtherData:    {url: 'auth/logout-other', method: 'POST', redirect: '/admin', makeRequest: false},

        facebookData:       {url: 'auth/facebook',     method: 'POST', redirect: '/'},
        googleData:         {url: 'auth/google',       method: 'POST', redirect: '/'},

        facebookOauth2Data: {
            url: 'https://www.facebook.com/v2.5/dialog/oauth',
            redirect: function () { return this.options.getUrl() + '/login/facebook'; },
            clientId: '',
            scope: 'email'
        },
        googleOauth2Data: {
            url: 'https://accounts.google.com/o/oauth2/auth',
            redirect: function () { return this.options.getUrl() + '/login/google'; },
            clientId: '',
            scope: 'https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.profile.emails.read'
        },

        // Internal

        getUrl:             _getUrl,
        cookieDomain:       _cookieDomain,
        parseUserData:      _parseUserData,
        tokenExpired:       _tokenExpired,
        check:              _check,

        transitionEach:     _transitionEach,
        routerBeforeEach:   _routerBeforeEach,
        requestIntercept:   _requestIntercept,
        responseIntercept:  _responseIntercept,

        // Contextual

        registerPerform:    _registerPerform,
        registerProcess:    _registerProcess,

        loginPerform:       _loginPerform,
        loginProcess:       _loginProcess,

        logoutPerform:      _logoutPerform,
        logoutProcess:      _logoutProcess,

        fetchPerform:       _fetchPerform,
        fetchProcess:       _fetchProcess,

        refreshPerform:     _refreshPerform,
        refreshProcess:     _refreshProcess,

        loginOtherPerform:  _loginOtherPerform,
        loginOtherProcess:  _loginOtherProcess,

        logoutOtherPerform: _logoutOtherPerform,
        logoutOtherProcess: _logoutOtherProcess,

        oauth2Perform:      _oauth2Perform
    };

    function Auth(Vue, options) {
        this.currentToken = null;

        this.options = __utils.extend(defaultOptions, [options || {}]);
        this.options.Vue = Vue;

        this.watch = new this.options.Vue({
            data: function () {
                return {
                    data: null,
                    loaded: false,
                    authenticated: null
                };
            }
        });

        // Init interceptors.
        this.options.router._beforeEach.call(this, this.options.routerBeforeEach, this.options.transitionEach);
        this.options.http._interceptor.call(this, this.options.requestIntercept, this.options.responseIntercept);
    }

    Auth.prototype.ready = function () {
        return this.watch.loaded;
    };

    Auth.prototype.user = function (data) {
        if (data) {
            this.watch.data = data;
        }

        return this.watch.data || {};
    };

    Auth.prototype.check = function (role) {
        return this.options.check.call(this, role);
    };

    Auth.prototype.other = function () {
        this.watch.data; // To fire watch

        return __token.get.call(this, 'other') ? true : false;
    };

    Auth.prototype.enableOther = function (data) {
        if (this.other()) {
            this.currentToken = null;
        }
    };

    Auth.prototype.disableOther = function (data) {
        if (this.other()) {
            this.currentToken = 'default';
        }
    };

    Auth.prototype.token = function (name) {
        return __token.get.call(this, name);
    };

    Auth.prototype.fetch = function (data) {
        __bindContext.call(this, 'fetch', data);
    };

    Auth.prototype.refresh = function (data) {
        __bindContext.call(this, 'refresh', data);
    };

    Auth.prototype.register = function (data) {
        __bindContext.call(this, 'register', data);
    };

    Auth.prototype.login = function (data) {
        __bindContext.call(this, 'login', data);
    };

    Auth.prototype.logout = function (data) {
        __bindContext.call(this, 'logout', data);
    };

    Auth.prototype.loginOther = function (data) {
        __bindContext.call(this, 'loginOther', data);
    };

    Auth.prototype.logoutOther = function (data) {
        __bindContext.call(this, 'logoutOther', data);
    };

    Auth.prototype.oauth2 = function (data) {
        __bindContext.call(this, 'oauth2', data);
    }

    return Auth;
};
<commit_msg>Fix logout to properly set authenticated to false.<commit_after>var __utils  = require('./lib/utils.js'),
    __token  = require('./lib/token.js'),
    __cookie = require('./lib/cookie.js')

module.exports = function () {

    // Private (used double underscore __).

    function __duckPunch(methodName, data) {
        var _this = this,
            success = data.success;

        data = __utils.extend(this.options[methodName + 'Data'], [data]);

        data.success = function (res) {
            data.success = success;

            _this.options[methodName + 'Process'].call(_this, res, data);
        };

        this.options.http._http.call(this, data);
    }

    function __bindContext(methodName, data) {
        var _auth = this.$auth;

        _auth.options[methodName + 'Perform'].call(_auth, _auth.options.router._bindData.call(_auth, data, this));
    }

    // Overrideable

    function _routerBeforeEach(cb) {

        if (this.options.tokenExpired.call(this)) {
            this.options.refreshPerform.call(this, {});
        }

        if (this.watch.authenticated === null && __token.get.call(this)) {
            if ( ! __cookie.exists.call(this)) {
                this.options.logoutProcess.call(this, null, {});

                this.watch.loaded = true

                return cb.call(this);
            }

            this.watch.authenticated = false
            this.options.fetchPerform.call(this, {success: cb, error: cb});
        } else {
            this.watch.loaded = true;
            return cb.call(this);
        }
    }

    function _transitionEach(routeAuth, cb) {
        routeAuth = __utils.toArray(routeAuth);

        if (routeAuth && (routeAuth === true || routeAuth.constructor === Array)) {
            if ( ! this.check()) {
                cb.call(this, this.options.authRedirect);
            }
            else if (routeAuth.constructor === Array && ! __utils.compare(routeAuth, this.watch.data[this.options.rolesVar])) {
                cb.call(this, this.options.forbiddenRedirect);
            }
            else {
                return cb();
            }
        }
        else if (routeAuth === false && this.check()) {
            cb.call(this, this.options.notFoundRedirect);
        }
        else {
            return cb();
        }
    }

    function _requestIntercept(req) {
        var token = __token.get.call(this);

        if (token) {
            this.options.auth.request.call(this, req, token);
        }

        return req;
    }

    function _responseIntercept(res) {
        var token;

        if (this.options.http._invalidToken) {
            this.options.http._invalidToken.call(this, res);
        }

        token = this.options.auth.response.call(this, res);

        if (token) {
            __token.set.call(this, null, token);
        }
    }

    function _parseUserData(data) {
        return data.data;
    }

    function _check(role) {
        if (this.watch.authenticated === true) {
            if (role) {
                return __utils.compare(role, this.watch.data[this.options.rolesVar]);
            }

            return true;
        }

        return false;
    }

    function _tokenExpired () {
        return ! this.watch.loaded && __token.get.call(this);
    }

    function _cookieDomain () {
        return window.location.hostname;
    }

    function _getUrl () {
        var port = window.location.port

        return window.location.protocol + '//' + window.location.hostname + (port ? ':' + port : '')
    }

    function _fetchPerform(data) {
        var _this = this,
            error = data.error;

        data.error = function (res) {
            _this.watch.loaded = true;

            if (error) { error.call(_this, res); }
        };

        __duckPunch.call(this, 'fetch', data);
    }

    function _fetchProcess(res, data) {
        this.watch.authenticated = true;
        this.watch.data = this.options.parseUserData.call(this, this.options.http._httpData.call(this, res));
        this.watch.loaded = true;

        if (data.success) { data.success.call(this, res); }
    }

    function _refreshPerform(data) {
        __duckPunch.call(this, 'refresh', data);
    }

    function _refreshProcess(res, data) {
        if (data.success) { data.success.call(this, res); }
    }

    function _registerPerform(data) {
        __duckPunch.call(this, 'register', data);
    }

    function _registerProcess(res, data) {
        if (data.autoLogin === true) {
            data = __utils.extend(data, [this.options.loginData]);

            this.options.loginPerform.call(this, data);
        }
        else {
            if (data.success) { data.success.call(this, res); }

            if (data.redirect) {
                this.options.router._routerGo.call(this, data.redirect);
            }
        }
    }

    function _loginPerform(data) {
        __duckPunch.call(this, 'login', data);
    }

    function _loginProcess(res, data) {
        var _this = this;

        __cookie.set.call(this, data.rememberMe);

        this.authenticated = null;

        this.options.fetchPerform.call(this, {
            success: function () {
                if (data.success) { data.success.call(this, res); }

                if (data.redirect && _this.options.check.call(_this)) {
                    _this.options.router._routerGo.call(_this, data.redirect);
                }
            }
        });
    }

    function _logoutPerform(data) {
        data = __utils.extend(this.options.logoutData, [data || {}]);

        if (data.makeRequest) {
            __duckPunch.call(this, 'logout', data);
        }
        else {
            this.options.logoutProcess.call(this, null, data);
        }
    }

    function _logoutProcess(res, data) {
        __cookie.delete.call(this);

        __token.delete.call(this, 'other');
        __token.delete.call(this, 'default');

        this.watch.authenticated = false;
        this.watch.data = null;

        if (data.success) { data.success.call(this, res, data); }

        if (data.redirect) {
            this.options.router._routerGo.call(this, data.redirect);
        }
    }

    function _loginOtherPerform(data) {
        var success,
            token = this.token.call(this); // (admin) token

        data = data || {};

        success = data.success;

        data.success = function () {

            // Reshuffle tokens here...
            __token.set.call(this, 'other', this.token.call(this));
            __token.set.call(this, 'default', token);

            if (success) { success.call(this); }
        };

        __duckPunch.call(this, 'loginOther', data);
    }

    function _loginOtherProcess(res, data) {
        var _this = this;

        this.options.fetchPerform.call(this, {
            success: function () {
                if (data.success) { data.success.call(this, res); }

                if (data.redirect && _this.options.check.call(_this)) {
                    _this.options.router._routerGo.call(_this, data.redirect);
                }
            }
        });
    }

    function _logoutOtherPerform(data) {
        data = __utils.extend(this.options.logoutOtherData, [data || {}]);

        if (data.makeRequest) {
            __duckPunch.call(this, 'logoutOther', data);
        }
        else {
            this.options.logoutOtherProcess.call(this, null, data);
        }
    }

    function _logoutOtherProcess(res, data) {
        __token.delete.call(this, 'other');

        this.options.fetchPerform.call(this, {
            success: function () {
                if (data.success) { data.success.call(this, res, data); }

                if (data.redirect) {
                    this.options.router._routerGo.call(this, data.redirect);
                }
            }
        });
    }

    function _oauth2Perform(data) {
        var state = {},
            params = '',
            query = {};

        if (data.code === true) {
            data = __utils.extend(this.options[data.provider + 'Data'], [data]);

            try {
                if (data.query.state) {
                    state = JSON.parse(decodeURIComponent(data.query.state));
                }
            }
            catch (e) {
                console.error('vue-auth:error There was an issue retrieving the state data.');
                state = {};
            }

            data.rememberMe = state.rememberMe === true;
            data.state = state;

            this.options.loginPerform.call(this, data);
        } else {
            data = __utils.extend(this.options[data.provider + 'Oauth2Data'], [data]);

            data.redirect = data.redirect.call(this);

            data.state = data.state || {};
            data.state.rememberMe = data.rememberMe === true;

            params = '?client_id=' + data.clientId + '&redirect_uri=' + data.redirect + '&scope=' + data.scope + '&response_type=code&state=' + encodeURIComponent(JSON.stringify(data.state));

            window.location = data.url + params;
        }
    }

    var defaultOptions = {

        // Variables

        rolesVar:          'roles',
        tokenName:         'auth-token',

        // Objects

        authRedirect:       {path: '/login'},
        forbiddenRedirect:  {path: '/403'},
        notFoundRedirect:   {path: '/404'},

        registerData:       {url: 'auth/register',     method: 'POST', redirect: '/login'},
        loginData:          {url: 'auth/login',        method: 'POST', redirect: '/'},
        logoutData:         {url: 'auth/logout',       method: 'POST', redirect: '/', makeRequest: false},
        oauth1Data:         {url: 'auth/login',        method: 'POST'},
        fetchData:          {url: 'auth/user',         method: 'GET'},
        refreshData:        {url: 'auth/refresh',      method: 'GET'},
        loginOtherData:     {url: 'auth/login-other',  method: 'POST', redirect: '/'},
        logoutOtherData:    {url: 'auth/logout-other', method: 'POST', redirect: '/admin', makeRequest: false},

        facebookData:       {url: 'auth/facebook',     method: 'POST', redirect: '/'},
        googleData:         {url: 'auth/google',       method: 'POST', redirect: '/'},

        facebookOauth2Data: {
            url: 'https://www.facebook.com/v2.5/dialog/oauth',
            redirect: function () { return this.options.getUrl() + '/login/facebook'; },
            clientId: '',
            scope: 'email'
        },
        googleOauth2Data: {
            url: 'https://accounts.google.com/o/oauth2/auth',
            redirect: function () { return this.options.getUrl() + '/login/google'; },
            clientId: '',
            scope: 'https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.profile.emails.read'
        },

        // Internal

        getUrl:             _getUrl,
        cookieDomain:       _cookieDomain,
        parseUserData:      _parseUserData,
        tokenExpired:       _tokenExpired,
        check:              _check,

        transitionEach:     _transitionEach,
        routerBeforeEach:   _routerBeforeEach,
        requestIntercept:   _requestIntercept,
        responseIntercept:  _responseIntercept,

        // Contextual

        registerPerform:    _registerPerform,
        registerProcess:    _registerProcess,

        loginPerform:       _loginPerform,
        loginProcess:       _loginProcess,

        logoutPerform:      _logoutPerform,
        logoutProcess:      _logoutProcess,

        fetchPerform:       _fetchPerform,
        fetchProcess:       _fetchProcess,

        refreshPerform:     _refreshPerform,
        refreshProcess:     _refreshProcess,

        loginOtherPerform:  _loginOtherPerform,
        loginOtherProcess:  _loginOtherProcess,

        logoutOtherPerform: _logoutOtherPerform,
        logoutOtherProcess: _logoutOtherProcess,

        oauth2Perform:      _oauth2Perform
    };

    function Auth(Vue, options) {
        this.currentToken = null;

        this.options = __utils.extend(defaultOptions, [options || {}]);
        this.options.Vue = Vue;

        this.watch = new this.options.Vue({
            data: function () {
                return {
                    data: null,
                    loaded: false,
                    authenticated: null
                };
            }
        });

        // Init interceptors.
        this.options.router._beforeEach.call(this, this.options.routerBeforeEach, this.options.transitionEach);
        this.options.http._interceptor.call(this, this.options.requestIntercept, this.options.responseIntercept);
    }

    Auth.prototype.ready = function () {
        return this.watch.loaded;
    };

    Auth.prototype.user = function (data) {
        if (data) {
            this.watch.data = data;
        }

        return this.watch.data || {};
    };

    Auth.prototype.check = function (role) {
        return this.options.check.call(this, role);
    };

    Auth.prototype.other = function () {
        this.watch.data; // To fire watch

        return __token.get.call(this, 'other') ? true : false;
    };

    Auth.prototype.enableOther = function (data) {
        if (this.other()) {
            this.currentToken = null;
        }
    };

    Auth.prototype.disableOther = function (data) {
        if (this.other()) {
            this.currentToken = 'default';
        }
    };

    Auth.prototype.token = function (name) {
        return __token.get.call(this, name);
    };

    Auth.prototype.fetch = function (data) {
        __bindContext.call(this, 'fetch', data);
    };

    Auth.prototype.refresh = function (data) {
        __bindContext.call(this, 'refresh', data);
    };

    Auth.prototype.register = function (data) {
        __bindContext.call(this, 'register', data);
    };

    Auth.prototype.login = function (data) {
        __bindContext.call(this, 'login', data);
    };

    Auth.prototype.logout = function (data) {
        __bindContext.call(this, 'logout', data);
    };

    Auth.prototype.loginOther = function (data) {
        __bindContext.call(this, 'loginOther', data);
    };

    Auth.prototype.logoutOther = function (data) {
        __bindContext.call(this, 'logoutOther', data);
    };

    Auth.prototype.oauth2 = function (data) {
        __bindContext.call(this, 'oauth2', data);
    }

    return Auth;
};
<|endoftext|>


<commit_before>/**
 * EmployeeController
 *
 * @description :: Server-side logic for managing employees
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

module.exports = {
	index: function (req, res) {
    res.view(null, {
        title: "Employee"
    });
  },
  // login: function (req, res) {
  //   res.view(null, {
  //       title: "Employee"
  //   });
  // },
	category: function (req, res) {
    res.view(null, {
        title: "Category"
    });
  }
};

<commit_msg>tag v0.1<commit_after>/**
 * EmployeeController
 *
 * @description :: Server-side logic for managing employees
 * @help        :: See http://sailsjs.org/#!/documentation/concepts/Controllers
 */

module.exports = {
	index: function (req, res) {
    res.view(null, {
        title: "Employee"
    });
  },
  // login: function (req, res) {
  //   res.view(null, {
  //       title: "Employee"
  //   });
  // },
	category: function (req, res) {
    res.view(null, {
        title: "Category"
    });
  }
};

<|endoftext|>


<commit_before>"use strict";

const path = require('path');

const chalk = require('chalk');

const Command = require('./API/Command');
const CommandManager = require('./CommandManager.js');
const Module = require('./API/Module');

class Main {
  constructor(opts) {
    process.on('unhandledRejection', function onError(err) {
      throw err;
    });

    this.packageOptions = require('../package.json');
    this.options = opts;

    this.commandManager = null;
    this.loadedModules = null;

    this.buildContainer();
    this.run();
  }

  buildRepl() {
    this.repl = require('repl').start('> ');
    this.repl.context.Module = Module;
    this.repl.context.Command = Command;
    this.repl.context.CommandManager = CommandManager;
  }

  buildContainer() {
    this.container = new Map();

    this.setupLogger();
    this.setupBrain();

    this.commandManager = new CommandManager(this.container);
    this.container.set('commandManager', this.commandManager);

    this.loadedModules = new Map();
    this.container.set('loadedModules', this.loadedModules);
  }

  setupLogger() {
    this.logger = require('./Logger')(path.join(__dirname, '..', 'logs'), 'cardinal');
    this.container.set('logger', this.logger);
  }

  setupBrain() {
    const RedisBrain = require('./Brain/Redis');

    this.brain = new RedisBrain();
    this.container.set('redisBrain', this.brain);
  }

  loadClient() {
    this.logger.info('Main::loadClient()');

    this.bot = require('./Bot')(this.container);
    this.container.set('bot', this.bot);
  }

  loadModules() {
    const modules = this.options.modules;

    this.logger.info('Main::loadModules()');

    for (const module of modules) {
      if (!(module.prototype instanceof Module)) {
        this.logger.warn(`${module.name} does not inherit from the Module class`);
        continue;
      }

      this.logger.info(`Initializing ${module.name}`);

      const moduleInstance = new (module)(this.container);
      this.loadedModules.set(module.name, moduleInstance);

      this.logger.info(`Initialized ${module.name}`);
    }
  }

  run() {
    console.log(chalk.blue(`\n\n\t${this.packageOptions.name} v${this.packageOptions.version} - by ${this.packageOptions.author}\n\n`));

    if (this.options.prefix) {
      this.logger.info(`Set command prefix to '${this.options.prefix}'`);
      this.commandManager.setPrefix(this.options.prefix);
    }

    this.loadClient();
    this.loadModules();

    this.bot.start();
  }
}

exports.initialize = function initialize(opts) {
  return new Main(opts);
};
<commit_msg>Main: signal CommandManager that discordie is loaded<commit_after>"use strict";

const path = require('path');

const chalk = require('chalk');

const Command = require('./API/Command');
const CommandManager = require('./CommandManager.js');
const Module = require('./API/Module');

class Main {
  constructor(opts) {
    process.on('unhandledRejection', function onError(err) {
      throw err;
    });

    this.packageOptions = require('../package.json');
    this.options = opts;

    this.commandManager = null;
    this.loadedModules = null;

    this.buildContainer();
    this.run();
  }

  buildRepl() {
    this.repl = require('repl').start('> ');
    this.repl.context.Module = Module;
    this.repl.context.Command = Command;
    this.repl.context.CommandManager = CommandManager;
  }

  buildContainer() {
    this.container = new Map();

    this.setupLogger();
    this.setupBrain();

    this.commandManager = new CommandManager(this.container);
    this.container.set('commandManager', this.commandManager);

    this.loadedModules = new Map();
    this.container.set('loadedModules', this.loadedModules);
  }

  setupLogger() {
    this.logger = require('./Logger')(path.join(__dirname, '..', 'logs'), 'cardinal');
    this.container.set('logger', this.logger);
  }

  setupBrain() {
    const RedisBrain = require('./Brain/Redis');

    this.brain = new RedisBrain();
    this.container.set('redisBrain', this.brain);
  }

  loadClient() {
    this.logger.info('Main::loadClient()');

    this.bot = require('./Bot')(this.container);
    this.container.set('bot', this.bot);

    this.commandManager.botReady();
  }

  loadModules() {
    const modules = this.options.modules;

    this.logger.info('Main::loadModules()');

    for (const module of modules) {
      if (!(module.prototype instanceof Module)) {
        this.logger.warn(`${module.name} does not inherit from the Module class`);
        continue;
      }

      this.logger.info(`Initializing ${module.name}`);

      const moduleInstance = new (module)(this.container);
      this.loadedModules.set(module.name, moduleInstance);

      this.logger.info(`Initialized ${module.name}`);
    }
  }

  run() {
    console.log(chalk.blue(`\n\n\t${this.packageOptions.name} v${this.packageOptions.version} - by ${this.packageOptions.author}\n\n`));

    if (this.options.prefix) {
      this.logger.info(`Set command prefix to '${this.options.prefix}'`);
      this.commandManager.setPrefix(this.options.prefix);
    }

    this.loadClient();
    this.loadModules();

    this.bot.start();
  }
}

exports.initialize = function initialize(opts) {
  return new Main(opts);
};
<|endoftext|>


<commit_before>import React, { PureComponent } from 'react';
import ReactSelect from 'react-select';
import PropTypes from 'prop-types';
import { IconChevronDownSmallOutline } from '@teamleader/ui-icons';
import { Button } from '../button';
import theme from './theme.css';

class Select extends PureComponent {
  state = {
    selectedOptions: [],
  };

  getControlStyles = (base, { isDisabled, isFocused }) => {
    const { inverse, size } = this.props;

    if(inverse) {
      return {
        ...base,
        backgroundColor: isDisabled ? '#3F4F61' : '#64788f',
        '&:hover': {
          borderColor: '#c1cede',
        },
        borderColor: isFocused ? '#c1cede' : isDisabled ? '#3F4F61' : '#64788f',
        boxShadow: isFocused ? '0 0 0 1px #c1cede' : 'none',
        minHeight: size === 'small' ? '30px' : size === 'medium' ? '36px' : '48px',
      };
    }

    return {
      ...base,
      backgroundColor: isDisabled ? '#e4e4e6' : '#fff',
      '&:hover': {
        borderColor: '#82828c',
      },
      borderColor: isFocused ? '#82828c' : isDisabled ? '#e4e4e6' : '#c0c0c4',
      boxShadow: isFocused ? '0 0 0 1px #82828c' : 'none',
      minHeight: size === 'small' ? '30px' : size === 'medium' ? '36px' : '48px',
    };
  };

  getIndicatorSeparatorStyles = (base) => ({
    ...base,
    backgroundColor: this.props.inverse ? '#64788f' : '#c0c0c4',
    marginTop: 0,
    marginBottom: 0,
  });

  getMenuStyles = (base) => ({
    ...base,
    backgroundColor: this.props.inverse ? '#64788f' : '#fff',
  });

  getOptionStyles = (base, { isFocused, isSelected }) => {
    if(this.props.inverse) {
      return {
        ...base,
        color: isFocused ? '#344b63' : '#fff',
        backgroundColor: isFocused ? '#c1cede' : isSelected ? '#344b63' : '#64788f',
        '&:active': {
          backgroundColor: '#344b63',
        },
      };
    }

    return {
      ...base,
      color: isSelected && !isFocused ? '#fff' : '#344b63',
      backgroundColor: isFocused ? '#e4e4e6' : isSelected ? '#82828c' : '#fff',
      '&:active': {
        backgroundColor: '#e4e4e6',
      },
    };
  };

  getPlaceholderStyles = (base, { isDisabled }) => {
    if(this.props.inverse) {
      return {
        ...base,
        color: isDisabled ? '#64788f' : '#c1cede',
      }
    }

    return {
      ...base,
      color: '#82828c',
    }
  };

  getDropDownIndicator = () => ({ isDisabled }) => (
    <Button
      className={theme['dropdown-indicator']}
      disabled={isDisabled}
      icon={<IconChevronDownSmallOutline />}
      size={this.props.size}
    />
  );

  getStyles = (size) => ({
    control: (base, { isDisabled, isFocused }) => this.getControlStyles(base, { isDisabled, isFocused }),
    indicatorSeparator: (base) => this.getIndicatorSeparatorStyles(base),
    menu: (base) => this.getMenuStyles(base),
    option: (base, { isFocused, isSelected }) => this.getOptionStyles(base, { isFocused, isSelected }),
    placeholder: (base, { isDisabled }) => this.getPlaceholderStyles(base, { isDisabled }),
  });

  handleChange = values => {
    this.setState({ selectedOptions: values });
  };

  render() {
    const { size, ...others } = this.props;
    const { selectedOptions } = this.state;

    return (
      <ReactSelect
        className={theme['select']}
        components={{ DropdownIndicator: this.getDropDownIndicator() }}
        onChange={this.handleChange}
        styles={this.getStyles(size)}
        value={selectedOptions}
        {...others}
      />
    );
  }
}

Select.propTypes = {
  /** Boolean indicating whether the select should render as inverse. */
  inverse: PropTypes.bool,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
};

Select.defaultProps = {
  inverse: false,
  size: 'medium',
};

export default Select;
<commit_msg>Override single value styles & get it from a class method<commit_after>import React, { PureComponent } from 'react';
import ReactSelect from 'react-select';
import PropTypes from 'prop-types';
import { IconChevronDownSmallOutline } from '@teamleader/ui-icons';
import { Button } from '../button';
import theme from './theme.css';

class Select extends PureComponent {
  state = {
    selectedOptions: [],
  };

  getControlStyles = (base, { isDisabled, isFocused }) => {
    const { inverse, size } = this.props;

    if(inverse) {
      return {
        ...base,
        backgroundColor: isDisabled ? '#3F4F61' : '#64788f',
        '&:hover': {
          borderColor: '#c1cede',
        },
        borderColor: isFocused ? '#c1cede' : isDisabled ? '#3F4F61' : '#64788f',
        boxShadow: isFocused ? '0 0 0 1px #c1cede' : 'none',
        minHeight: size === 'small' ? '30px' : size === 'medium' ? '36px' : '48px',
      };
    }

    return {
      ...base,
      backgroundColor: isDisabled ? '#e4e4e6' : '#fff',
      '&:hover': {
        borderColor: '#82828c',
      },
      borderColor: isFocused ? '#82828c' : isDisabled ? '#e4e4e6' : '#c0c0c4',
      boxShadow: isFocused ? '0 0 0 1px #82828c' : 'none',
      minHeight: size === 'small' ? '30px' : size === 'medium' ? '36px' : '48px',
    };
  };

  getIndicatorSeparatorStyles = (base) => ({
    ...base,
    backgroundColor: this.props.inverse ? '#64788f' : '#c0c0c4',
    marginTop: 0,
    marginBottom: 0,
  });

  getMenuStyles = (base) => ({
    ...base,
    backgroundColor: this.props.inverse ? '#64788f' : '#fff',
  });

  getOptionStyles = (base, { isFocused, isSelected }) => {
    if(this.props.inverse) {
      return {
        ...base,
        color: isFocused ? '#344b63' : '#fff',
        backgroundColor: isFocused ? '#c1cede' : isSelected ? '#344b63' : '#64788f',
        '&:active': {
          backgroundColor: '#344b63',
        },
      };
    }

    return {
      ...base,
      color: isSelected && !isFocused ? '#fff' : '#344b63',
      backgroundColor: isFocused ? '#e4e4e6' : isSelected ? '#82828c' : '#fff',
      '&:active': {
        backgroundColor: '#e4e4e6',
      },
    };
  };

  getPlaceholderStyles = (base, { isDisabled }) => {
    if(this.props.inverse) {
      return {
        ...base,
        color: isDisabled ? '#64788f' : '#c1cede',
      }
    }

    return {
      ...base,
      color: '#82828c',
    }
  };

  getSingleValueStyles = (base) => ({
    ...base,
    color: this.props.inverse ? '#fff' : '#2a3b4d',
  });

  getDropDownIndicator = () => ({ isDisabled }) => (
    <Button
      className={theme['dropdown-indicator']}
      disabled={isDisabled}
      icon={<IconChevronDownSmallOutline />}
      size={this.props.size}
    />
  );

  getStyles = (size) => ({
    control: (base, { isDisabled, isFocused }) => this.getControlStyles(base, { isDisabled, isFocused }),
    indicatorSeparator: (base) => this.getIndicatorSeparatorStyles(base),
    menu: (base) => this.getMenuStyles(base),
    option: (base, { isFocused, isSelected }) => this.getOptionStyles(base, { isFocused, isSelected }),
    placeholder: (base, { isDisabled }) => this.getPlaceholderStyles(base, { isDisabled }),
    singleValue: (base) => this.getSingleValueStyles(base),
  });

  handleChange = values => {
    this.setState({ selectedOptions: values });
  };

  render() {
    const { size, ...others } = this.props;
    const { selectedOptions } = this.state;

    return (
      <ReactSelect
        className={theme['select']}
        components={{ DropdownIndicator: this.getDropDownIndicator() }}
        onChange={this.handleChange}
        styles={this.getStyles(size)}
        value={selectedOptions}
        {...others}
      />
    );
  }
}

Select.propTypes = {
  /** Boolean indicating whether the select should render as inverse. */
  inverse: PropTypes.bool,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
};

Select.defaultProps = {
  inverse: false,
  size: 'medium',
};

export default Select;
<|endoftext|>


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

    angular
        .module('app.canvas')
        .component('pfCanvas', PfCanvas());

    /* @ngInject */
    function PfCanvas() {
        var component = {
            templateUrl: 'app/canvas/canvas.html',
            controller: CanvasCtrl,
            controllerAs: 'vm'
        };

        return component;
    }

    CanvasCtrl.$inject = ['$log'];

    /* @ngInject */
    function CanvasCtrl($log) {
      var vm = this;
      var canvas = document.getElementById('pfCanvas');
      var ctx = canvas.getContext('2d');

      var src = 'images/mario.png';
      var parent = document.getElementById('canvas');

      var angleInDegrees=0;

      initialize();

      function initialize() {
				window.addEventListener('resize', resizeCanvas, false);
				resizeCanvas();
			}

			function redraw() {
        openPicture(src);
			}

			function resizeCanvas() {
        canvas.width = parent.offsetWidth;
        canvas.height = parent.offsetHeight;
				redraw();
			}

      function openPicture(src) {
        clearCanvas();
        var img=new Image();
        img.crossOrigin="anonymous";
        img.onload=start;
        img.src=src;
        function start(){
          var ratio=calculateProportionalAspectRatio(img.width,img.height,canvas.width,canvas.height);
          ctx.drawImage(img,(canvas.width - img.width*ratio)/2, (canvas.height - img.height*ratio)/2
              ,img.width*ratio,img.height*ratio);
        }
        function calculateProportionalAspectRatio(srcWidth, srcHeight, maxWidth, maxHeight) {
          return(Math.min(maxWidth / srcWidth, maxHeight / srcHeight));
        }
      }

      function clearCanvas() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
      }
    }
})();
<commit_msg>Fix errors according to gulp lint<commit_after>(function() {
    'use strict';

    angular
        .module('app.canvas')
        .component('pfCanvas', PfCanvas());

    /* @ngInject */
    function PfCanvas() {
        var component = {
            templateUrl: 'app/canvas/canvas.html',
            controller: CanvasCtrl,
            controllerAs: 'vm'
        };

        return component;
    }

    CanvasCtrl.$inject = ['$log', '$window', '$document'];

    /* @ngInject */
    function CanvasCtrl($log, $window, $document) {
      var vm = this;
      var canvas = $window.document.getElementById('pfCanvas');

      var ctx = canvas.getContext('2d');

      var src = 'images/mario.png';

      var parent = $window.document.getElementById('canvas');

      var angleInDegrees=0;

      initialize();

      function initialize() {
				$window.addEventListener('resize', resizeCanvas, false);
				resizeCanvas();
			}

			function redraw() {
        openPicture(src);
			}

			function resizeCanvas() {
        canvas.width = parent.offsetWidth;
        canvas.height = parent.offsetHeight;
				redraw();
			}

      function openPicture(src) {
        clearCanvas();
        var img=new Image();
        img.crossOrigin="anonymous";
        img.onload=start;
        img.src=src;
        function start(){
          var ratio=calculateProportionalAspectRatio(img.width,img.height,canvas.width,canvas.height);
          ctx.drawImage(img,(canvas.width - img.width*ratio)/2, (canvas.height - img.height*ratio)/2
              ,img.width*ratio,img.height*ratio);
        }
        function calculateProportionalAspectRatio(srcWidth, srcHeight, maxWidth, maxHeight) {
          return(Math.min(maxWidth / srcWidth, maxHeight / srcHeight));
        }
      }

      function clearCanvas() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
      }
    }
})();
<|endoftext|>


<commit_before>'use strict';

const smoochBot = require('smooch-bot');
const MemoryLock = smoochBot.MemoryLock;
const SmoochApiStore = smoochBot.SmoochApiStore;
const SmoochApiBot = smoochBot.SmoochApiBot;
const StateMachine = smoochBot.StateMachine;
const app = require('../app');
const script = require('../script');
const SmoochCore = require('smooch-core');
const jwt = require('../jwt');
const fs = require('fs');

class BetterSmoochApiBot extends SmoochApiBot {
    constructor(options) {
        super(options);
    }

    sendImage(imageFileName) {
        const api = this.store.getApi();
        let message = Object.assign({
            role: 'appMaker'
        }, {
            name: this.name,
            avatarUrl: this.avatarUrl
        });
        var real = fs.realpathSync(imageFileName);
        let source = fs.readFileSync(real);

        return api.conversations.uploadImage(this.userId, source, message);
    }
}

const name = 'SmoochBot';
const avatarUrl = 'https://s.gravatar.com/avatar/f91b04087e0125153623a3778e819c0a?s=80';
const store = new SmoochApiStore({
    jwt
});
const lock = new MemoryLock();

function createWebhook(smoochCore, target) {
    return smoochCore.webhooks.create({
            target,
            triggers: ['message:appUser']
        })
        .then((res) => {
            console.log('Smooch webhook created at target', res.webhook.target);
            return smoochCore.webhooks.create({
                        target,
                        triggers: ['postback']
                    })
                    .then((res) => {
                        console.log('Smooch postback webhook created at target', res.webhook.target);
                    })
                    .catch((err) => {
                        console.error('Error creating Smooch webhook:', err);
                        console.error(err.stack);
                    });
            }
        )
        .catch((err) => {
            console.error('Error creating Smooch webhook:', err);
            console.error(err.stack);
        });
}

// Create a webhook if one doesn't already exist
if (process.env.SERVICE_URL) {
    const target = process.env.SERVICE_URL.replace(/\/$/, '') + '/webhook';
    const smoochCore = new SmoochCore({
        jwt
    });
    smoochCore.webhooks.list()
        .then((res) => {
            if (!res.webhooks.some((w) => w.target === target)) {
                createWebhook(smoochCore, target);
            }
        });
}

app.post('/webhook', function(req, res, next) {
    var isPostback = req.body.trigger == "postback";
    var msg = '';

    const appUser = req.body.appUser;
    const userId = appUser.userId || appUser._id;
    const stateMachine = new StateMachine({
        script,
        bot: new BetterSmoochApiBot({
            name,
            avatarUrl,
            lock,
            store,
            userId
        })
    });

    if(!isPostback) {
        const messages = req.body.messages.reduce((prev, current) => {
            if (current.role === 'appUser') {
                prev.push(current);
            }
            return prev;
        }, []);

        if (messages.length === 0 && !isTrigger) {
            return res.end();
        }

        msg = messages[0];
    } else {
        msg = req.body.postbacks[0];
        msg.text = msg.action.text;
    }

    stateMachine.receiveMessage(msg)
        .then(() => res.end())
        .catch((err) => {
            console.error('SmoochBot error:', err);
            console.error(err.stack);
            res.end();
        });
});

var server = app.listen(process.env.PORT || 8000, function() {
    var host = server.address().address;
    var port = server.address().port;

    console.log('Smooch Bot listening at http://%s:%s', host, port);
});<commit_msg>Delete index.js<commit_after><|endoftext|>


<commit_before>import { parseResponse } from "./http.js"

const mentionsRegExp = /\B@([a-zA-Z][a-zA-Z0-9_-]{0,17})/g
const urlsRegExp = /\b(https?:\/\/[\-A-Za-z0-9+&@#\/%?=~_|!:,\.;]*[\-A-Za-z0-9+&@#\/%=~_|])/gi
const imageExtRegExp = /(\.gif|\.jpg|\.jpeg|\.png|\.avif|\.apng|\.webp|\.bmp|\.ico|\.tif|\.tiff|\.svg)$/
const videoExtRegExp = /(\.mp4|\.webm|\.3gp|\.mov)$/
const audioExtRegExp = /(\.wav|\.mp3|\.aac|\.ogg|\.flac|\.m4a)$/

export const reUsername = /^[a-zA-Z][a-zA-Z0-9_-]{0,17}$/

export function isLocalhost() {
    return ["localhost", "127.0.0.1"].includes(window.location.hostname)
}

export function isObject(x) {
    return typeof x === "object" && x !== null
}

export function isPlainObject(x) {
    return isObject(x) && !Array.isArray(x)
}

export function smartTrim(s) {
    return s
        .split("\n")
        .map(s => s.replace(/(\s)+/g, "$1").trim())
        .join("\n")
        .replace(/(\n){2,}/g, "$1$1")
        .trim()
}

/**
 * @param {string} s
 */
export function escapeHTML(s) {
    return s
        .replace(/&/g, "&")
        .replace(/</g, "<")
        .replace(/>/g, ">")
        .replace(/"/g, """)
        .replace(/"/g, "'")
}

/**
 * @param {string} s
 */
export function linkify(s) {
    return s
        .replace(mentionsRegExp, '@$1')
        .replace(urlsRegExp, '$1')
}

/**
 * @param {string|Date} date
 */
export function ago(date) {
    if (!(date instanceof Date)) {
        date = new Date(date)
    }
    const now = new Date()
    let diff = (now.getTime() - date.getTime()) / 1000
    if (diff <= 60) {
        return "Just now"
    } else if ((diff /= 60) < 60) {
        return (diff | 0) + "m"
    } else if ((diff /= 60) < 24) {
        return (diff | 0) + "h"
    } else if ((diff /= 24) < 7) {
        return (diff | 0) + "d"
    }
    let text = String(date).split(" ")[1] + " " + date.getDate()
    if (now.getFullYear() !== date.getFullYear()) {
        text += ", " + date.getFullYear()
    }
    return text
}

/**
 * @param {Node} oldNode
 * @param {Node} newNode
 */
export function replaceNode(oldNode, newNode) {
    oldNode.parentNode.insertBefore(newNode, oldNode)
    oldNode.parentNode.removeChild(oldNode)
    return newNode
}

/**
 * @param {string} html
 */
export function el(html) {
    const template = document.createElement("template")
    template.innerHTML = html
    return template.content.childElementCount === 1
        ? template.content.firstElementChild
        : template.content
}

/**
 * @param {ParentNode} el
 */
export async function collectMedia(el) {
    const media = /** @type {Node[]} */ ([])
    for (const link of Array.from(el.querySelectorAll("a"))) {
        if (link.hostname === window.location.hostname && link.pathname.startsWith("/users/")) {
            continue
        }

        const imgurID = findImgurID(link.href)
        if (imgurID !== null) {
            const img = document.createElement("img")
            // TODO: better detect imgur image extension.
            img.src = "https://i.imgur.com/" + encodeURIComponent(imgurID) + ".png"
            const a = document.createElement("a")
            a.href = link.href
            a.target = "_blank"
            a.rel = "noopener"
            a.className = "media-item imgur"
            a.appendChild(img)
            media.push(a)
            continue
        }

        const youtubeVideoID = findYouTubeVideoID(link.href)
        if (youtubeVideoID !== null) {
            const img = document.createElement("img")
            img.src = `https://img.youtube.com/vi/${youtubeVideoID}/0.jpg`
            // img.crossOrigin = ""
            img.width = 540
            img.height = 304
            const a = document.createElement("a")
            a.href = link.href
            a.target = "_blank"
            a.rel = "noopener"
            a.className = "media-item youtube-video-wrapper"
            a.appendChild(img)
            a.onclick = ev => {
                ev.preventDefault()
                ev.stopImmediatePropagation()

                const iframe = document.createElement("iframe")
                iframe.src = "https://www.youtube.com/embed/" + encodeURIComponent(youtubeVideoID) + "?autoplay=1"
                iframe.setAttribute("frameborder", "0")
                iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                iframe.allowFullscreen = true
                iframe.className = "media-item youtube"
                a.insertAdjacentElement("afterend", iframe)
                a.remove()
            }
            media.push(a)
            continue
        }

        const coubVideoID = findCoubVideoID(link.href)
        if (coubVideoID !== null) {
            const iframe = document.createElement("iframe")
            iframe.src = "https://coub.com/embed/" + encodeURIComponent(coubVideoID) + "?muted=false&autostart=false&originalSize=true&startWithHD=true"
            iframe.setAttribute("frameborder", "0")
            iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
            iframe.allowFullscreen = true
            iframe.className = "media-item coub"
            media.push(iframe)
            continue
        }

        if (isSoundCloudURL(link.href)) {
            await getSoundCloudIframe(link.href).then(iframe => {
                iframe.className = "media-item soundcloud"
                media.push(iframe)
            }).catch(console.error)
            continue
        }

        if (isTweet(link.href)) {
            await getTweetEmbed(link.href).then(node => {
                const div = document.createElement("div")
                div.className = "media-item tweet"
                div.appendChild(node)
                media.push(div)
            }).catch(console.error)
            continue
        }

        const mt = await mediaType(link.href).catch(() => null)
        if (mt === "image") {
            const img = document.createElement("img")
            img.src = link.href
            const a = document.createElement("a")
            a.href = link.href
            a.target = "_blank"
            a.rel = "noopener"
            a.className = "media-item"
            a.appendChild(img)
            media.push(a)
            continue
        }

        if (mt === "audio") {
            const audio = document.createElement("audio")
            audio.src = link.href
            audio.controls = true
            audio.loop = true
            audio.volume = 0.5
            audio.autoplay = false
            audio.className = "media-item"
            media.push(audio)
            continue
        }

        if (mt === "video") {
            const video = document.createElement("video")
            video.src = link.href
            video.controls = true
            video.loop = true
            video.volume = 0.5
            video.autoplay = false
            video.muted = true
            video.className = "media-item"
            media.push(video)
            continue
        }
    }
    return media
}

/**
 * @param {string} url
 */
async function mediaType(url) {
    if (imageExtRegExp.test(url)) {
        return "image"
    }

    if (videoExtRegExp.test(url)) {
        return "video"
    }

    if (audioExtRegExp.test(url)) {
        return "audio"
    }

    const endpoint = "/api/proxy?target=" + encodeURIComponent(url)
    return fetch(endpoint, { method: "HEAD", redirect: "follow" }).then(res => {
        const ct = res.headers.get("Content-Type")
        if (ct.startsWith("image/")) {
            return "image"
        }
        if (ct.startsWith("video/")) {
            return "video"
        }
        if (ct.startsWith("audio/")) {
            return "audio"
        }

        return ""
    }).catch(_ => "")
}

function findImgurID(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "imgur.com") {
            return null
        }

        // /{id}
        const parts = url.pathname.split("/")
        if (parts.length === 2 && parts[0] === "" && !parts[1].includes(".")) {
            return parts[1]
        }
    } catch (_) { }
    return null
}

/***
 * @param {string} href
 * @returns {string|null}
 */
function findYouTubeVideoID(href) {
    try {
        const url = new URL(href)
        if (url.hostname === "youtube.com" || url.hostname === "www.youtube.com" || url.hostname === "m.youtube.com") {
            if (url.pathname === "/watch" && url.searchParams.has("v")) {
                return decodeURIComponent(url.searchParams.get("v"))
            }

            // /embed/{id}
            const parts = url.pathname.split("/")
            if (parts.length === 3 && parts[0] === "" && parts[1] === "embed") {
                return decodeURIComponent(parts[2])
            }
        }

        if (url.hostname === "youtu.be") {
            // /{id}
            const parts = url.pathname.split("/")
            if (parts.length === 2 && parts[0] === "") {
                return decodeURIComponent(parts[1])
            }
        }
    } catch (_) { }
    return null
}

function findCoubVideoID(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "coub.com") {
            return null
        }

        const parts = url.pathname.split("/")
        // /view/{id}
        // /embed/{id}
        if (parts.length === 3 && parts[0] === "" && (parts[1] === "view" || parts[1] === "embed")) {
            return decodeURIComponent(parts[2])
        }
    } catch (_) { }
    return null
}

function isSoundCloudURL(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "soundcloud.com") {
            return false
        }

        // /{username}/{slug}
        const parts = url.pathname.split("/")
        return parts.length == 3 && parts[0] === ""
    } catch (_) { }
    return false
}

function getSoundCloudIframe(url) {
    return fetch(`https://soundcloud.com/oembed?format=json&url=${encodeURIComponent(url)}`).then(parseResponse).then(body => {
        const tmpl = document.createElement("template")
        tmpl.innerHTML = body.html
        return tmpl.content.querySelector("iframe")
    })
}

function isTweet(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "twitter.com") {
            return false
        }

        // /{username}/status/{id}
        const parts = url.pathname.split("/")
        return parts.length === 4 && parts[0] === "" && parts[2] === "status"
    } catch (_) { }
    return false
}

function getTweetEmbed(url) {
    return fetchJSONP(`https://publish.twitter.com/oembed?url=${encodeURIComponent(url)}&theme=dark`).then(parseResponse).then(body => {
        const tmpl = document.createElement("template")
        tmpl.innerHTML = body.html
        return tmpl.content
    })
}

let jsonPCounter = 0
function fetchJSONP(url) {
    return new Promise(resolve => {
        jsonPCounter++
        const name = "_jsonp_" + String(jsonPCounter) + String(Math.random()).substr(2)
        url += url.match(/\?/) ? "&" : "?"
        url += "callback=" + encodeURIComponent(name)

        const script = document.createElement("script")
        script.src = url

        window[name] = json => {
            resolve(new Response(JSON.stringify(json)))
            script.remove()
            delete window[name]
        };

        document.body.appendChild(script)
    })
}

/**
 * @param {ArrayBuffer} buff
 * @returns {string}
 */
export function arrayBufferToBase64(buff) {
    return btoa(
        new Uint8Array(buff)
            .reduce((data, byte) => data + String.fromCharCode(byte), "")
    )
        .replace(/\+/g, "-")
        .replace(/\//g, "_")
        .replace(/=/g, "")
}

/**
 * @param {string} s
 * @returns {ArrayBuffer}
 */
export function base64ToArrayBuffer(s) {
    return Uint8Array.from(atob(s), c => c.charCodeAt(0))
}
<commit_msg>web/static: embed from youtube music<commit_after>import { parseResponse } from "./http.js"

const mentionsRegExp = /\B@([a-zA-Z][a-zA-Z0-9_-]{0,17})/g
const urlsRegExp = /\b(https?:\/\/[\-A-Za-z0-9+&@#\/%?=~_|!:,\.;]*[\-A-Za-z0-9+&@#\/%=~_|])/gi
const imageExtRegExp = /(\.gif|\.jpg|\.jpeg|\.png|\.avif|\.apng|\.webp|\.bmp|\.ico|\.tif|\.tiff|\.svg)$/
const videoExtRegExp = /(\.mp4|\.webm|\.3gp|\.mov)$/
const audioExtRegExp = /(\.wav|\.mp3|\.aac|\.ogg|\.flac|\.m4a)$/

export const reUsername = /^[a-zA-Z][a-zA-Z0-9_-]{0,17}$/

export function isLocalhost() {
    return ["localhost", "127.0.0.1"].includes(window.location.hostname)
}

export function isObject(x) {
    return typeof x === "object" && x !== null
}

export function isPlainObject(x) {
    return isObject(x) && !Array.isArray(x)
}

export function smartTrim(s) {
    return s
        .split("\n")
        .map(s => s.replace(/(\s)+/g, "$1").trim())
        .join("\n")
        .replace(/(\n){2,}/g, "$1$1")
        .trim()
}

/**
 * @param {string} s
 */
export function escapeHTML(s) {
    return s
        .replace(/&/g, "&")
        .replace(/</g, "<")
        .replace(/>/g, ">")
        .replace(/"/g, """)
        .replace(/"/g, "'")
}

/**
 * @param {string} s
 */
export function linkify(s) {
    return s
        .replace(mentionsRegExp, '@$1')
        .replace(urlsRegExp, '$1')
}

/**
 * @param {string|Date} date
 */
export function ago(date) {
    if (!(date instanceof Date)) {
        date = new Date(date)
    }
    const now = new Date()
    let diff = (now.getTime() - date.getTime()) / 1000
    if (diff <= 60) {
        return "Just now"
    } else if ((diff /= 60) < 60) {
        return (diff | 0) + "m"
    } else if ((diff /= 60) < 24) {
        return (diff | 0) + "h"
    } else if ((diff /= 24) < 7) {
        return (diff | 0) + "d"
    }
    let text = String(date).split(" ")[1] + " " + date.getDate()
    if (now.getFullYear() !== date.getFullYear()) {
        text += ", " + date.getFullYear()
    }
    return text
}

/**
 * @param {Node} oldNode
 * @param {Node} newNode
 */
export function replaceNode(oldNode, newNode) {
    oldNode.parentNode.insertBefore(newNode, oldNode)
    oldNode.parentNode.removeChild(oldNode)
    return newNode
}

/**
 * @param {string} html
 */
export function el(html) {
    const template = document.createElement("template")
    template.innerHTML = html
    return template.content.childElementCount === 1
        ? template.content.firstElementChild
        : template.content
}

/**
 * @param {ParentNode} el
 */
export async function collectMedia(el) {
    const media = /** @type {Node[]} */ ([])
    for (const link of Array.from(el.querySelectorAll("a"))) {
        if (link.hostname === window.location.hostname && link.pathname.startsWith("/users/")) {
            continue
        }

        const imgurID = findImgurID(link.href)
        if (imgurID !== null) {
            const img = document.createElement("img")
            // TODO: better detect imgur image extension.
            img.src = "https://i.imgur.com/" + encodeURIComponent(imgurID) + ".png"
            const a = document.createElement("a")
            a.href = link.href
            a.target = "_blank"
            a.rel = "noopener"
            a.className = "media-item imgur"
            a.appendChild(img)
            media.push(a)
            continue
        }

        const youtubeVideoID = findYouTubeVideoID(link.href)
        if (youtubeVideoID !== null) {
            const img = document.createElement("img")
            img.src = `https://img.youtube.com/vi/${youtubeVideoID}/0.jpg`
            // img.crossOrigin = ""
            img.width = 540
            img.height = 304
            const a = document.createElement("a")
            a.href = link.href
            a.target = "_blank"
            a.rel = "noopener"
            a.className = "media-item youtube-video-wrapper"
            a.appendChild(img)
            a.onclick = ev => {
                ev.preventDefault()
                ev.stopImmediatePropagation()

                const iframe = document.createElement("iframe")
                iframe.src = "https://www.youtube.com/embed/" + encodeURIComponent(youtubeVideoID) + "?autoplay=1"
                iframe.setAttribute("frameborder", "0")
                iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                iframe.allowFullscreen = true
                iframe.className = "media-item youtube"
                a.insertAdjacentElement("afterend", iframe)
                a.remove()
            }
            media.push(a)
            continue
        }

        const coubVideoID = findCoubVideoID(link.href)
        if (coubVideoID !== null) {
            const iframe = document.createElement("iframe")
            iframe.src = "https://coub.com/embed/" + encodeURIComponent(coubVideoID) + "?muted=false&autostart=false&originalSize=true&startWithHD=true"
            iframe.setAttribute("frameborder", "0")
            iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
            iframe.allowFullscreen = true
            iframe.className = "media-item coub"
            media.push(iframe)
            continue
        }

        if (isSoundCloudURL(link.href)) {
            await getSoundCloudIframe(link.href).then(iframe => {
                iframe.className = "media-item soundcloud"
                media.push(iframe)
            }).catch(console.error)
            continue
        }

        if (isTweet(link.href)) {
            await getTweetEmbed(link.href).then(node => {
                const div = document.createElement("div")
                div.className = "media-item tweet"
                div.appendChild(node)
                media.push(div)
            }).catch(console.error)
            continue
        }

        const mt = await mediaType(link.href).catch(() => null)
        if (mt === "image") {
            const img = document.createElement("img")
            img.src = link.href
            const a = document.createElement("a")
            a.href = link.href
            a.target = "_blank"
            a.rel = "noopener"
            a.className = "media-item"
            a.appendChild(img)
            media.push(a)
            continue
        }

        if (mt === "audio") {
            const audio = document.createElement("audio")
            audio.src = link.href
            audio.controls = true
            audio.loop = true
            audio.volume = 0.5
            audio.autoplay = false
            audio.className = "media-item"
            media.push(audio)
            continue
        }

        if (mt === "video") {
            const video = document.createElement("video")
            video.src = link.href
            video.controls = true
            video.loop = true
            video.volume = 0.5
            video.autoplay = false
            video.muted = true
            video.className = "media-item"
            media.push(video)
            continue
        }
    }
    return media
}

/**
 * @param {string} url
 */
async function mediaType(url) {
    if (imageExtRegExp.test(url)) {
        return "image"
    }

    if (videoExtRegExp.test(url)) {
        return "video"
    }

    if (audioExtRegExp.test(url)) {
        return "audio"
    }

    const endpoint = "/api/proxy?target=" + encodeURIComponent(url)
    return fetch(endpoint, { method: "HEAD", redirect: "follow" }).then(res => {
        const ct = res.headers.get("Content-Type")
        if (ct.startsWith("image/")) {
            return "image"
        }
        if (ct.startsWith("video/")) {
            return "video"
        }
        if (ct.startsWith("audio/")) {
            return "audio"
        }

        return ""
    }).catch(_ => "")
}

function findImgurID(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "imgur.com") {
            return null
        }

        // /{id}
        const parts = url.pathname.split("/")
        if (parts.length === 2 && parts[0] === "" && !parts[1].includes(".")) {
            return parts[1]
        }
    } catch (_) { }
    return null
}

/***
 * @param {string} href
 * @returns {string|null}
 */
function findYouTubeVideoID(href) {
    try {
        const url = new URL(href)
        if (url.hostname === "youtube.com" || url.hostname === "www.youtube.com" || url.hostname === "m.youtube.com") {
            if (url.pathname === "/watch" && url.searchParams.has("v")) {
                return decodeURIComponent(url.searchParams.get("v"))
            }

            // /embed/{id}
            const parts = url.pathname.split("/")
            if (parts.length === 3 && parts[0] === "" && parts[1] === "embed") {
                return decodeURIComponent(parts[2])
            }
        }

        if (url.hostname === "youtu.be") {
            // /{id}
            const parts = url.pathname.split("/")
            if (parts.length === 2 && parts[0] === "") {
                return decodeURIComponent(parts[1])
            }
        }

        if (url.hostname === "music.youtube.com" && url.pathname === "/watch" && url.searchParams.has("v")) {
            return decodeURIComponent(url.searchParams.get("v"))
        }
    } catch (_) { }
    return null
}

function findCoubVideoID(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "coub.com") {
            return null
        }

        const parts = url.pathname.split("/")
        // /view/{id}
        // /embed/{id}
        if (parts.length === 3 && parts[0] === "" && (parts[1] === "view" || parts[1] === "embed")) {
            return decodeURIComponent(parts[2])
        }
    } catch (_) { }
    return null
}

function isSoundCloudURL(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "soundcloud.com") {
            return false
        }

        // /{username}/{slug}
        const parts = url.pathname.split("/")
        return parts.length == 3 && parts[0] === ""
    } catch (_) { }
    return false
}

function getSoundCloudIframe(url) {
    return fetch(`https://soundcloud.com/oembed?format=json&url=${encodeURIComponent(url)}`).then(parseResponse).then(body => {
        const tmpl = document.createElement("template")
        tmpl.innerHTML = body.html
        return tmpl.content.querySelector("iframe")
    })
}

function isTweet(href) {
    try {
        const url = new URL(href)
        if (url.hostname !== "twitter.com") {
            return false
        }

        // /{username}/status/{id}
        const parts = url.pathname.split("/")
        return parts.length === 4 && parts[0] === "" && parts[2] === "status"
    } catch (_) { }
    return false
}

function getTweetEmbed(url) {
    return fetchJSONP(`https://publish.twitter.com/oembed?url=${encodeURIComponent(url)}&theme=dark`).then(parseResponse).then(body => {
        const tmpl = document.createElement("template")
        tmpl.innerHTML = body.html
        return tmpl.content
    })
}

let jsonPCounter = 0
function fetchJSONP(url) {
    return new Promise(resolve => {
        jsonPCounter++
        const name = "_jsonp_" + String(jsonPCounter) + String(Math.random()).substr(2)
        url += url.match(/\?/) ? "&" : "?"
        url += "callback=" + encodeURIComponent(name)

        const script = document.createElement("script")
        script.src = url

        window[name] = json => {
            resolve(new Response(JSON.stringify(json)))
            script.remove()
            delete window[name]
        };

        document.body.appendChild(script)
    })
}

/**
 * @param {ArrayBuffer} buff
 * @returns {string}
 */
export function arrayBufferToBase64(buff) {
    return btoa(
        new Uint8Array(buff)
            .reduce((data, byte) => data + String.fromCharCode(byte), "")
    )
        .replace(/\+/g, "-")
        .replace(/\//g, "_")
        .replace(/=/g, "")
}

/**
 * @param {string} s
 * @returns {ArrayBuffer}
 */
export function base64ToArrayBuffer(s) {
    return Uint8Array.from(atob(s), c => c.charCodeAt(0))
}
<|endoftext|>


<commit_before>import React from 'react';

const Warning = () => {
  return (

Har du opplevd noe ugreit?

        Online har to kontaktpersoner som kan hjelpe under fadderukene, Thea Karin Fladby (21) og Sindre Langaard (23).
        Vi ønsker at alle skal ha det bra og føle seg trygge under fadderukene. Derfor håper vi at du tar kontakt dersom
        du har opplevd noe ubehagelig. Ser du at noen andre opplever noe ubehagelig er det viktig å huske på at du også
        har et ansvar for å si ifra. Vi tar imot alt, og om du er i tvil er det bare å sende oss en melding. Tar du
        kontakt med oss vil all informasjon behandles strengt konfidensielt. Vi kan bistå med alt fra en uformell prat
        til å hjelpe deg med å oppsøke profesjonell hjelp eller rådgivning.

        Om situasjonen tilsier at du trenger å snakke med noen umiddelbart kan du alltid ringe leder Mathias Fossum på
        958 29 020 eller faddersjef Robin Lund Sadun på 90 77 55 81. Du kan nå Thea og Sinder på 966 46 705.

        Send varsling

  );
};

export default Warning;
<commit_msg>quick fix of incorrect name<commit_after>import React from 'react';

const Warning = () => {
  return (

Har du opplevd noe ugreit?

        Online har to kontaktpersoner som kan hjelpe under fadderukene, Thea Karin Fladby (21) og Sindre Langaard (23).
        Vi ønsker at alle skal ha det bra og føle seg trygge under fadderukene. Derfor håper vi at du tar kontakt dersom
        du har opplevd noe ubehagelig. Ser du at noen andre opplever noe ubehagelig er det viktig å huske på at du også
        har et ansvar for å si ifra. Vi tar imot alt, og om du er i tvil er det bare å sende oss en melding. Tar du
        kontakt med oss vil all informasjon behandles strengt konfidensielt. Vi kan bistå med alt fra en uformell prat
        til å hjelpe deg med å oppsøke profesjonell hjelp eller rådgivning.

        Om situasjonen tilsier at du trenger å snakke med noen umiddelbart kan du alltid ringe leder Mathias Fossum på
        958 29 020 eller faddersjef Robin Lund Sadun på 90 77 55 81. Du kan nå Thea og Sindre på 966 46 705.

        Send varsling

  );
};

export default Warning;
<|endoftext|>


<commit_before>export { InputsOutputs } from "./BoundsArraySet/InputsOutputs.js";
export { ConvBiasActivation } from "./BoundsArraySet/ConvBiasActivation.js";
<commit_msg>Update BoundsArraySet.js<commit_after>export { InputsOutputs } from "./BoundsArraySet/BoundsArraySet_InputsOutputs.js";
export { ConvBiasActivation } from "./BoundsArraySet/BoundsArraySet_ConvBiasActivation.js";
export { Pointwise } from "./BoundsArraySet/BoundsArraySet_Pointwise.js";
export { Depthwise } from "./BoundsArraySet/BoundsArraySet_Depthwise.js";
<|endoftext|>


<commit_before>(function($) {

	var refreshAfterImport = function(e) {
		// Check for a message <div>, an indication that the form has been submitted.
		var existingFormMessage = $($(this).contents()).find('.message');
		if(existingFormMessage && existingFormMessage.html()) {
			// Refresh member listing
			var memberTableField = $(window.parent.document).find('#Form_EditForm_Members').get(0);
			if(memberTableField) memberTableField.refresh();

			// Refresh tree
			var tree = $(window.parent.document).find('#sitetree').get(0);
			if(tree) tree.reload();
		}
	};

	/**
	 * Refresh the member listing every time the import iframe is loaded,
	 * which is most likely a form submission.
	 */
	$(window).bind('load', function(e) {
		$('#MemberImportFormIframe,#GroupImportFormIframe').concrete({
			onmatch: function() {
				this._super();

				// TODO concrete can't seem to bind to iframe load events
				$(this).bind('load', refreshAfterImport);
			}
		});
	})

	/**
	 * Delete selected folders through "batch actions" tab.
	 */
	$(document).ready(function() {
		$('#Form_BatchActionsForm').concrete('ss').register(
			// TODO Hardcoding of base URL
			'admin/security/batchactions/delete',
			function(ids) {
				var confirmed = confirm(
					ss.i18n.sprintf(
						ss.i18n._t('SecurityAdmin.BATCHACTIONSDELETECONFIRM'),
						ids.length
					)
				);
				return (confirmed) ? ids : false;
			}
		);
	});

	$.concrete('ss', function($){
		$('#Form_EditForm .Actions #Form_EditForm_action_addmember').concrete({
			onclick: function(e) {
				// CAUTION: Assumes that a MemberTableField-instance is present as an editing form
				var t = $('#Form_EditForm_Members');
				t[0].openPopup(
					null,
					$('base').attr('href') + t.find('a.addlink').attr('href'),
					t.find('table')[0]
				);
				return false;
			}
		});
	});

}(jQuery));<commit_msg>ENHANCEMENT Disabling/checking permission checkboxes in admin/security when 'ADMIN' permission is selected<commit_after>(function($) {

	var refreshAfterImport = function(e) {
		// Check for a message <div>, an indication that the form has been submitted.
		var existingFormMessage = $($(this).contents()).find('.message');
		if(existingFormMessage && existingFormMessage.html()) {
			// Refresh member listing
			var memberTableField = $(window.parent.document).find('#Form_EditForm_Members').get(0);
			if(memberTableField) memberTableField.refresh();

			// Refresh tree
			var tree = $(window.parent.document).find('#sitetree').get(0);
			if(tree) tree.reload();
		}
	};

	/**
	 * Refresh the member listing every time the import iframe is loaded,
	 * which is most likely a form submission.
	 */
	$(window).bind('load', function(e) {
		$('#MemberImportFormIframe,#GroupImportFormIframe').concrete({
			onmatch: function() {
				this._super();

				// TODO concrete can't seem to bind to iframe load events
				$(this).bind('load', refreshAfterImport);
			}
		});
	})

	/**
	 * Delete selected folders through "batch actions" tab.
	 */
	$(document).ready(function() {
		$('#Form_BatchActionsForm').concrete('ss').register(
			// TODO Hardcoding of base URL
			'admin/security/batchactions/delete',
			function(ids) {
				var confirmed = confirm(
					ss.i18n.sprintf(
						ss.i18n._t('SecurityAdmin.BATCHACTIONSDELETECONFIRM'),
						ids.length
					)
				);
				return (confirmed) ? ids : false;
			}
		);
	});

	$.concrete('ss', function($){
		$('#Form_EditForm .Actions #Form_EditForm_action_addmember').concrete({
			onclick: function(e) {
				// CAUTION: Assumes that a MemberTableField-instance is present as an editing form
				var t = $('#Form_EditForm_Members');
				t[0].openPopup(
					null,
					$('base').attr('href') + t.find('a.addlink').attr('href'),
					t.find('table')[0]
				);
				return false;
			}
		});

		/**
		 * Automatically check and disable all checkboxes if ADMIN permissions are selected.
		 * As they're disabled, any changes won't be submitted (which is intended behaviour),
		 * checking all boxes is purely presentational.
		 */
		$('#Form_EditForm #Permissions .checkbox[value=ADMIN]').concrete({
			onmatch: function() {
				this.toggleCheckboxes();

				this._super();
			},
			onclick: function(e) {
				this.toggleCheckboxes();
			},
			toggleCheckboxes: function() {
				var self = this, checkboxes = this.parents('.permissioncheckboxset:eq(0)').find('.checkbox').not(this);
				if(this.is(':checked')) {
					checkboxes.each(function() {
						$(this).data('SecurityAdmin.oldChecked', $(this).attr('checked'));
						$(this).attr('disabled', 'disabled');
						$(this).attr('checked', 'checked');
					});
				} else {
					checkboxes.each(function() {
						$(this).attr('checked', $(this).data('SecurityAdmin.oldChecked'));
						$(this).attr('disabled', '');
					});
				}
			}
		});
	});

}(jQuery));<|endoftext|>


<commit_before>import $ from 'jquery';
import {Flummox} from 'flummox';
import ApplicationStore from 'common/src/data/application/application-store';
import ApplicationActions from 'common/src/data/application/application-actions';
import List from 'application/src/application-list/application-list';

const FLUX_ID = 'application';

class MockFlux extends Flummox {
    constructor() {
        super();

        this.createActions(FLUX_ID, ApplicationActions);
        this.createStore(FLUX_ID, ApplicationStore, this);
    }
}

describe('The application list view', () => {
    var flux,
        list;

    beforeEach(() => {
        flux = new MockFlux();
        list = new List({
            flux: flux
        });
    });

    it('should not display a list without applications', () => {
        expect(list.$el.find('ul').length).to.equal(0);
    });

    it('should display a list of applications', () => {
        flux
        .getStore(FLUX_ID)
        .receiveApplications([{
            id: 'kio',
            name: 'Kio'
        }, {
            id: 'yourturn',
            name: 'Yourturn'
        }]);

        expect(list.$el.find('ul > li').length).to.equal(2);
    });
});<commit_msg>#70 lint errors<commit_after>/* globals expect */
import {Flummox} from 'flummox';
import ApplicationStore from 'common/src/data/application/application-store';
import ApplicationActions from 'common/src/data/application/application-actions';
import List from 'application/src/application-list/application-list';

const FLUX_ID = 'application';

class MockFlux extends Flummox {
    constructor() {
        super();

        this.createActions(FLUX_ID, ApplicationActions);
        this.createStore(FLUX_ID, ApplicationStore, this);
    }
}

describe('The application list view', () => {
    var flux,
        list;

    beforeEach(() => {
        flux = new MockFlux();
        list = new List({
            flux: flux
        });
    });

    it('should not display a list without applications', () => {
        expect(list.$el.find('ul').length).to.equal(0);
    });

    it('should display a list of applications', () => {
        flux
        .getStore(FLUX_ID)
        .receiveApplications([{
            id: 'kio',
            name: 'Kio'
        }, {
            id: 'yourturn',
            name: 'Yourturn'
        }]);

        expect(list.$el.find('ul > li').length).to.equal(2);
    });
});<|endoftext|>