<commit_before>/*
 * Copyright 2019 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This module is based on the Haskell mode from CodeMirror.
//
// CodeMirror is copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

'use strict';

CodeMirror.defineMode('codeworld', (config, modeConfig) => {
    // This is a regular expression used in multiple contexts.
    const MULTICHAR_ESCAPE_REGEX =
        '\\\\NUL|\\\\SOH|\\\\STX|\\\\ETX|\\\\EOT|\\\\ENQ|\\\\ACK|\\\\BEL|\\\\BS|' +
        '\\\\HT|\\\\LF|\\\\VT|\\\\FF|\\\\CR|\\\\SO|\\\\SI|\\\\DLE|\\\\DC1|\\\\DC2|' +
        '\\\\DC3|\\\\DC4|\\\\NAK|\\\\SYN|\\\\ETB|\\\\CAN|\\\\EM|\\\\SUB|\\\\ESC|' +
        '\\\\FS|\\\\GS|\\\\RS|\\\\US|\\\\SP|\\\\DEL';
    const CONTINUATION_REGEX = '\\s*(?:[:!#$%&*+./<=>?@\\^|~,)\\]}-]|where|in|of|deriving)';
    const RE_WHITESPACE = /[ \v\t\f]+/;
    const RE_STARTMETA = /{-#/;
    const RE_STARTCOMMENT = /{-/;
    const RE_DASHES = /--+(?=$|[^:!#$%&*+./<=>?@\\^|~-]+)/;
    const RE_QUAL =
        /[A-Z][A-Za-z_0-9']*\.(?=[A-Za-z_:!#$%&*+./<=>?@\\^|~]|-[^-])/;
    const RE_VARID = /[a-z_][A-Za-z_0-9']*/;
    const RE_CONID = /[A-Z][A-Za-z_0-9']*/;
    const RE_VARSYM = /[!#$%&*+./<=>?@\\^|~-][:!#$%&*+./<=>?@\\^|~-]*/;
    const RE_CONSYM = /:[:!#$%&*+./<=>?@\\^|~-]*/;
    const RE_NUMBER =
        /[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?|0[oO][0-7]+|0[xX][0-9a-fA-F]+/;
    const RE_CHAR = new RegExp(
        `'(?:[^\\\\']|\\\\[abfnrtv\\\\"']|\\\\^[A-Z@[\\\\\\]^_]|${MULTICHAR_ESCAPE_REGEX})'`);
    const RE_STRING = new RegExp(
        `"(?:[^\\\\"]|\\\\[abfnrtv\\\\"'&]|\\\\^[A-Z@[\\\\\\]^_]|${MULTICHAR_ESCAPE_REGEX})*"`);
    const RE_OPENBRACKET = /[([{]/;
    const RE_CLOSEBRACKET = /[)\]}]/;
    const RE_INCOMMENT = /(?:[^{-]|-(?=$|[^}])|\{(?=$|[^-]))*/;
    const RE_ENDCOMMENT = /-}/;
    const RE_ELECTRIC_START = new RegExp(`^${CONTINUATION_REGEX}`);
    const RE_ELECTRIC_INPUT = new RegExp(`^${CONTINUATION_REGEX}$`);

    // The state has the following properties:
    //
    // func:         The function to tokenize the remaining stream.
    // commentLevel: Number of levels of block comments.
    // continued:    The last token cannot end an expression or layout statement.
    // contexts:     Grouping contexts, from outermost to innermost.
    //               Array of objects
    //               {
    //                 value: '{'. '(', '[', 'let', or 'other'
    //                 column: base indent column for the context,
    //                 ln: line at which the context started
    //                 ch: column at which the context started
    //                 functionName: string (optional)
    //                 argIndex: integer (optional)
    //               }
    // lastTokens:   Array of last up-to-two tokens encountered.
    // line:         Current line number

    function isBracket(context) {
        return context.value.length === 1;
    }

    function normal(stream, column, state) {
        if (stream.match(RE_WHITESPACE)) return null;

        if (stream.match(RE_STARTMETA)) {
            state.func = blockComment('meta');
            ++state.commentLevel;
            return state.func(stream, column, state);
        }

        if (stream.match(RE_STARTCOMMENT)) {
            state.func = blockComment('comment');
            ++state.commentLevel;
            return state.func(stream, column, state);
        }

        if (stream.match(RE_DASHES)) {
            stream.skipToEnd();
            return 'comment';
        }

        state.continued = false;

        if (stream.match(RE_QUAL)) return 'qualifier';
        if (stream.match(RE_CONID)) return 'variable-2';
        if (stream.match(RE_NUMBER)) return 'number';
        if (stream.match(RE_CHAR) || stream.match(RE_STRING)) return 'string';
        if (stream.match(RE_CLOSEBRACKET)) return 'bracket';
        if (stream.match(RE_OPENBRACKET)) {
            state.continued = true;
            return 'bracket';
        }

        if (stream.match(RE_VARID)) {
            if (['case', 'of', 'class', 'data', 'instance', 'deriving',
                'do', 'if', 'then', 'else', 'import', 'infix', 'infixl',
                'infixr', 'instance', 'let', 'in', 'module', 'newtype',
                'type', 'where'
            ].indexOf(stream.current()) >= 0) {
                state.continued = true;
            }
            return 'variable';
        }

        if (stream.match(RE_VARSYM)) {
            state.continued = true;
            return 'variable';
        }

        if (stream.match(RE_CONSYM)) {
            state.continued = true;
            return 'variable-2';
        }

        if (stream.eat(',')) {
            state.continued = true;
            return 'comma';
        }

        stream.next();
        return 'error';
    }

    function blockComment(tokenType) {
        return (stream, column, state) => {
            if (state.commentLevel === 0) {
                state.func = normal;
                return tokenType;
            }

            stream.match(RE_INCOMMENT);
            if (stream.match(RE_STARTCOMMENT)) {
                ++state.commentLevel;
                return state.func(stream, column, state);
            }
            if (stream.match(RE_ENDCOMMENT)) {
                --state.commentLevel;
                return state.func(stream, column, state);
            }
            return tokenType;
        };
    }

    const wellKnownWords = (() => {
        const result = {};

        const keywords = [
            'case', 'class', 'data', 'default', 'deriving',
            'do', 'else', 'foreign',
            'if', 'import', 'in', 'infix', 'infixl',
            'infixr', 'instance', 'let',
            'module', 'newtype', 'of', 'then', 'type',
            'where', '_', '..', ':',
            '=', '::', '\\', '<-', '->', '@', '~', '=>',
            '|'
        ];

        for (let i = 0; i < keywords.length; ++i) {
            result[
                keywords[i]] = 'keyword';
        }

        const override = modeConfig.overrideKeywords;
        if (override) {
            for (const word in override) {
                if (override.hasOwnProperty(word)) {
                    result[word] = override[word];
                }
            }
        }

        return result;
    })();

    function parseToken(stream, state) {
        const t = state.func(stream, stream.column(), state);
        if (['variable', 'variable-2'].indexOf(t) !== -1) {
            const w = stream.current();
            if (wellKnownWords.hasOwnProperty(w)) {
                return wellKnownWords[w];
            }
        }
        return t;
    }

    function opening(bracket) {
        if (bracket === ')') return '(';
        if (bracket === ']') return '[';
        if (bracket === '}') return '{';
        if (bracket === 'in') return 'let';
    }

    function updateLayout(token, column, style, state) {
        // Close any implicit contexts when there are tokens in columns to
        // the left.
        const toClose = state.contexts.findIndex(ctx => !isBracket(ctx) && ctx.column > column);
        let foundLet = false;
        if (toClose >= 0) {
            foundLet = state.contexts[toClose].value === 'let';
            while (state.contexts.length > toClose) state.contexts.pop();
        }

        // Create any new implicit contexts called for by layout rules.
        if (state.lastTokens.length === 0) {
            if (token !== 'module' && token !== '{') {
                state.contexts.push({
                    value: 'where', // There's an implied "module Main where"
                    column: column,
                    ln: state.line,
                    ch: column
                });
            }
        } else {
            const triggered = state.lastTokens.slice(-1).join(' ') === 'where' ||
                state.lastTokens.slice(-1).join(' ') === 'of' ||
                state.lastTokens.slice(-1).join(' ') === 'do' ||
                state.lastTokens.slice(-1).join(' ') === 'let' ||
                state.lastTokens.slice(-2).join(' ') === '\\ case';

            if (triggered && token !== '{') {
                state.contexts.push({
                    value: state.lastTokens.slice(-1)[0],
                    column: column,
                    ln: state.line,
                    ch: column
                });
            }
        }

        // Update lastTokens so that layout rules can be applied next time.
        state.lastTokens = state.lastTokens.slice(-1);
        state.lastTokens.push(token);

        // Close contexts when syntax demands that we do so.
        if (token === ',') {
            // Close implicit contexts on comma.
            while (state.contexts.length) {
                const topContext = state.contexts.pop();
                if (!state.contexts.length || isBracket(topContext)) {
                    if (topContext.hasOwnProperty('argIndex')) topContext.argIndex++;
                    state.contexts.push(topContext);
                    break;
                }
            }
        } else if (RE_CLOSEBRACKET.test(token) || (!foundLet && token === 'in')) {
            // Close contexts inside brackets when the brackets are closed.
            // Note that let/in counts as a bracket pair for this purposes.
            state.contexts.reverse();
            const reverseIndex = state.contexts.findIndex(ctx => ctx.value === opening(token));
            state.contexts.reverse();
            if (reverseIndex >= 0) {
                const index = state.contexts.length - reverseIndex - 1;
                while (state.contexts.length > index) state.contexts.pop();
                if (token !== 'in') {
                    // Update the style to indicate bracket level.
                    const level = state.contexts.filter(isBracket).length;
                    if (level <= 6) style = `${style}-${level}`;
                }
            }
        } else if (token === 'where') {
            const topContext = () => state.contexts[state.contexts.length - 1];
            while (state.contexts.length > 0 && ['let', 'of', 'do', 'case'].indexOf(topContext().value) >= 0) {
                state.contexts.pop();
            }
        }

        // Decide if this is a new layout statement, whether it's in a new layout context
        // or an existing one.  If so, then any pre-existing brackets should be closed.
        const layoutCtx = state.contexts.findIndex(ctx => ctx.column === column);
        const isLayout = layoutCtx >= 0 && !isBracket(state.contexts[layoutCtx]);
        if (isLayout) {
            state.contexts = state.contexts.slice(0, layoutCtx + 1);
        }

        // Open new contexts for brackets.  These should be inside the
        // implicit contexts created by layout.
        if (RE_OPENBRACKET.test(token)) {
            const level = state.contexts.filter(isBracket).length;
            if (level <= 6) style = `${style}-${level}`;

            let functionName = null;
            if (token === '(' && state.lastTokens.length > 1) {
                const nextToLast = state.lastTokens[state.lastTokens.length - 2];
                if (RE_VARID.test(nextToLast) || RE_CONID.test(nextToLast)) {
                    functionName = nextToLast;
                }
            }

            let newColumn = 0;
            if (state.contexts.length > 0) {
                newColumn = state.contexts[state.contexts.length - 1].column + config.indentUnit;
            }
            state.contexts.push({
                value: token,
                column: newColumn,
                ln: state.line,
                ch: column,
                functionName,
                argIndex: 0
            });
        }

        return isLayout ? `${style} layout` : style;
    }

    return {
        startState: () => {
            return {
                func: normal,
                commentLevel: 0,
                continued: false,
                contexts: [],
                lastTokens: [],
                line: 0
            };
        },
        copyState: state => {
            return {
                func: state.func,
                commentLevel: state.commentLevel,
                continued: state.continued,
                contexts: state.contexts.map(ctx => {
                    return {
                        value: ctx.value,
                        column: ctx.column,
                        ln: ctx.ln,
                        ch: ctx.ch,
                        functionName: ctx.functionName,
                        argIndex: ctx.argIndex || 0
                    };
                }),
                lastTokens: state.lastTokens.map(t => t),
                line: state.line
            };
        },
        token: (stream, state) => {
            const column = stream.column();
            let style = parseToken(stream, state);

            // Ignore whitespaces and comments for layout purposes.
            if (style !== null && style !== 'comment' && style !== 'meta') {
                style = updateLayout(stream.current(), column, style, state);
            }

            if (stream.eol()) state.line++;
            return style;
        },
        blankLine: state => {
            state.line++;
        },
        indent: (state, textAfter) => {
            if (state.commentLevel > 0 || state.contexts.length < 1) return CodeMirror.Pass;

            // Find the top layout level.  If the next token closes a layout, then
            // this is the layout above the one that's closed, but an extra indent is
            // needed.  Otherwise, it's the top of the stack.
            let topLayout = state.contexts.length - 1;
            const token = textAfter.match(/^(in\b|where\b|[,)\]}])/);
            if (token && token[0] === ',') {
                while (topLayout > 0 && !isBracket(state.contexts[topLayout])) {
                    --topLayout;
                }
            } else if (token && token[0] === 'where') {
                while (topLayout > 0 && ['let', 'of', 'do', 'case'].indexOf(state.contexts[topLayout].value) >= 0) {
                    --topLayout;
                }
            } else if (token && state.contexts.findIndex(ctx => ctx.value === opening(token[0])) >= 1) {
                while (state.contexts[topLayout].value !== opening(token[0])) {
                    --topLayout;
                }
                --topLayout;
            }

            const layoutIndent = state.contexts[topLayout].column || 0;

            if (/^(where|[|])/.test(textAfter)) return layoutIndent + Math.ceil(config.indentUnit / 2);
            else if (state.continued || RE_ELECTRIC_START.test(textAfter)) return layoutIndent + config.indentUnit;
            else return layoutIndent;
        },
        electricInput: RE_ELECTRIC_INPUT,
        blockCommentStart: '{-',
        blockCommentEnd: '-}',
        lineComment: '--'
    };
});
<commit_msg>Re-add indent for then and else<commit_after>/*
 * Copyright 2019 The CodeWorld Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This module is based on the Haskell mode from CodeMirror.
//
// CodeMirror is copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

'use strict';

CodeMirror.defineMode('codeworld', (config, modeConfig) => {
    // This is a regular expression used in multiple contexts.
    const MULTICHAR_ESCAPE_REGEX =
        '\\\\NUL|\\\\SOH|\\\\STX|\\\\ETX|\\\\EOT|\\\\ENQ|\\\\ACK|\\\\BEL|\\\\BS|' +
        '\\\\HT|\\\\LF|\\\\VT|\\\\FF|\\\\CR|\\\\SO|\\\\SI|\\\\DLE|\\\\DC1|\\\\DC2|' +
        '\\\\DC3|\\\\DC4|\\\\NAK|\\\\SYN|\\\\ETB|\\\\CAN|\\\\EM|\\\\SUB|\\\\ESC|' +
        '\\\\FS|\\\\GS|\\\\RS|\\\\US|\\\\SP|\\\\DEL';
    const CONTINUATION_REGEX = '\\s*(?:[:!#$%&*+./<=>?@\\^|~,)\\]}-]|where|in|of|then|else|deriving)';
    const RE_WHITESPACE = /[ \v\t\f]+/;
    const RE_STARTMETA = /{-#/;
    const RE_STARTCOMMENT = /{-/;
    const RE_DASHES = /--+(?=$|[^:!#$%&*+./<=>?@\\^|~-]+)/;
    const RE_QUAL =
        /[A-Z][A-Za-z_0-9']*\.(?=[A-Za-z_:!#$%&*+./<=>?@\\^|~]|-[^-])/;
    const RE_VARID = /[a-z_][A-Za-z_0-9']*/;
    const RE_CONID = /[A-Z][A-Za-z_0-9']*/;
    const RE_VARSYM = /[!#$%&*+./<=>?@\\^|~-][:!#$%&*+./<=>?@\\^|~-]*/;
    const RE_CONSYM = /:[:!#$%&*+./<=>?@\\^|~-]*/;
    const RE_NUMBER =
        /[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?|0[oO][0-7]+|0[xX][0-9a-fA-F]+/;
    const RE_CHAR = new RegExp(
        `'(?:[^\\\\']|\\\\[abfnrtv\\\\"']|\\\\^[A-Z@[\\\\\\]^_]|${MULTICHAR_ESCAPE_REGEX})'`);
    const RE_STRING = new RegExp(
        `"(?:[^\\\\"]|\\\\[abfnrtv\\\\"'&]|\\\\^[A-Z@[\\\\\\]^_]|${MULTICHAR_ESCAPE_REGEX})*"`);
    const RE_OPENBRACKET = /[([{]/;
    const RE_CLOSEBRACKET = /[)\]}]/;
    const RE_INCOMMENT = /(?:[^{-]|-(?=$|[^}])|\{(?=$|[^-]))*/;
    const RE_ENDCOMMENT = /-}/;
    const RE_ELECTRIC_START = new RegExp(`^${CONTINUATION_REGEX}`);
    const RE_ELECTRIC_INPUT = new RegExp(`^${CONTINUATION_REGEX}$`);

    // The state has the following properties:
    //
    // func:         The function to tokenize the remaining stream.
    // commentLevel: Number of levels of block comments.
    // continued:    The last token cannot end an expression or layout statement.
    // contexts:     Grouping contexts, from outermost to innermost.
    //               Array of objects
    //               {
    //                 value: '{'. '(', '[', 'let', or 'other'
    //                 column: base indent column for the context,
    //                 ln: line at which the context started
    //                 ch: column at which the context started
    //                 functionName: string (optional)
    //                 argIndex: integer (optional)
    //               }
    // lastTokens:   Array of last up-to-two tokens encountered.
    // line:         Current line number

    function isBracket(context) {
        return context.value.length === 1;
    }

    function normal(stream, column, state) {
        if (stream.match(RE_WHITESPACE)) return null;

        if (stream.match(RE_STARTMETA)) {
            state.func = blockComment('meta');
            ++state.commentLevel;
            return state.func(stream, column, state);
        }

        if (stream.match(RE_STARTCOMMENT)) {
            state.func = blockComment('comment');
            ++state.commentLevel;
            return state.func(stream, column, state);
        }

        if (stream.match(RE_DASHES)) {
            stream.skipToEnd();
            return 'comment';
        }

        state.continued = false;

        if (stream.match(RE_QUAL)) return 'qualifier';
        if (stream.match(RE_CONID)) return 'variable-2';
        if (stream.match(RE_NUMBER)) return 'number';
        if (stream.match(RE_CHAR) || stream.match(RE_STRING)) return 'string';
        if (stream.match(RE_CLOSEBRACKET)) return 'bracket';
        if (stream.match(RE_OPENBRACKET)) {
            state.continued = true;
            return 'bracket';
        }

        if (stream.match(RE_VARID)) {
            if (['case', 'of', 'class', 'data', 'instance', 'deriving',
                'do', 'if', 'then', 'else', 'import', 'infix', 'infixl',
                'infixr', 'instance', 'let', 'in', 'module', 'newtype',
                'type', 'where'
            ].indexOf(stream.current()) >= 0) {
                state.continued = true;
            }
            return 'variable';
        }

        if (stream.match(RE_VARSYM)) {
            state.continued = true;
            return 'variable';
        }

        if (stream.match(RE_CONSYM)) {
            state.continued = true;
            return 'variable-2';
        }

        if (stream.eat(',')) {
            state.continued = true;
            return 'comma';
        }

        stream.next();
        return 'error';
    }

    function blockComment(tokenType) {
        return (stream, column, state) => {
            if (state.commentLevel === 0) {
                state.func = normal;
                return tokenType;
            }

            stream.match(RE_INCOMMENT);
            if (stream.match(RE_STARTCOMMENT)) {
                ++state.commentLevel;
                return state.func(stream, column, state);
            }
            if (stream.match(RE_ENDCOMMENT)) {
                --state.commentLevel;
                return state.func(stream, column, state);
            }
            return tokenType;
        };
    }

    const wellKnownWords = (() => {
        const result = {};

        const keywords = [
            'case', 'class', 'data', 'default', 'deriving',
            'do', 'else', 'foreign',
            'if', 'import', 'in', 'infix', 'infixl',
            'infixr', 'instance', 'let',
            'module', 'newtype', 'of', 'then', 'type',
            'where', '_', '..', ':',
            '=', '::', '\\', '<-', '->', '@', '~', '=>',
            '|'
        ];

        for (let i = 0; i < keywords.length; ++i) {
            result[
                keywords[i]] = 'keyword';
        }

        const override = modeConfig.overrideKeywords;
        if (override) {
            for (const word in override) {
                if (override.hasOwnProperty(word)) {
                    result[word] = override[word];
                }
            }
        }

        return result;
    })();

    function parseToken(stream, state) {
        const t = state.func(stream, stream.column(), state);
        if (['variable', 'variable-2'].indexOf(t) !== -1) {
            const w = stream.current();
            if (wellKnownWords.hasOwnProperty(w)) {
                return wellKnownWords[w];
            }
        }
        return t;
    }

    function opening(bracket) {
        if (bracket === ')') return '(';
        if (bracket === ']') return '[';
        if (bracket === '}') return '{';
        if (bracket === 'in') return 'let';
    }

    function updateLayout(token, column, style, state) {
        // Close any implicit contexts when there are tokens in columns to
        // the left.
        const toClose = state.contexts.findIndex(ctx => !isBracket(ctx) && ctx.column > column);
        let foundLet = false;
        if (toClose >= 0) {
            foundLet = state.contexts[toClose].value === 'let';
            while (state.contexts.length > toClose) state.contexts.pop();
        }

        // Create any new implicit contexts called for by layout rules.
        if (state.lastTokens.length === 0) {
            if (token !== 'module' && token !== '{') {
                state.contexts.push({
                    value: 'where', // There's an implied "module Main where"
                    column: column,
                    ln: state.line,
                    ch: column
                });
            }
        } else {
            const triggered = state.lastTokens.slice(-1).join(' ') === 'where' ||
                state.lastTokens.slice(-1).join(' ') === 'of' ||
                state.lastTokens.slice(-1).join(' ') === 'do' ||
                state.lastTokens.slice(-1).join(' ') === 'let' ||
                state.lastTokens.slice(-2).join(' ') === '\\ case';

            if (triggered && token !== '{') {
                state.contexts.push({
                    value: state.lastTokens.slice(-1)[0],
                    column: column,
                    ln: state.line,
                    ch: column
                });
            }
        }

        // Update lastTokens so that layout rules can be applied next time.
        state.lastTokens = state.lastTokens.slice(-1);
        state.lastTokens.push(token);

        // Close contexts when syntax demands that we do so.
        if (token === ',') {
            // Close implicit contexts on comma.
            while (state.contexts.length) {
                const topContext = state.contexts.pop();
                if (!state.contexts.length || isBracket(topContext)) {
                    if (topContext.hasOwnProperty('argIndex')) topContext.argIndex++;
                    state.contexts.push(topContext);
                    break;
                }
            }
        } else if (RE_CLOSEBRACKET.test(token) || (!foundLet && token === 'in')) {
            // Close contexts inside brackets when the brackets are closed.
            // Note that let/in counts as a bracket pair for this purposes.
            state.contexts.reverse();
            const reverseIndex = state.contexts.findIndex(ctx => ctx.value === opening(token));
            state.contexts.reverse();
            if (reverseIndex >= 0) {
                const index = state.contexts.length - reverseIndex - 1;
                while (state.contexts.length > index) state.contexts.pop();
                if (token !== 'in') {
                    // Update the style to indicate bracket level.
                    const level = state.contexts.filter(isBracket).length;
                    if (level <= 6) style = `${style}-${level}`;
                }
            }
        } else if (token === 'where') {
            const topContext = () => state.contexts[state.contexts.length - 1];
            while (state.contexts.length > 0 && ['let', 'of', 'do', 'case'].indexOf(topContext().value) >= 0) {
                state.contexts.pop();
            }
        }

        // Decide if this is a new layout statement, whether it's in a new layout context
        // or an existing one.  If so, then any pre-existing brackets should be closed.
        const layoutCtx = state.contexts.findIndex(ctx => ctx.column === column);
        const isLayout = layoutCtx >= 0 && !isBracket(state.contexts[layoutCtx]);
        if (isLayout) {
            state.contexts = state.contexts.slice(0, layoutCtx + 1);
        }

        // Open new contexts for brackets.  These should be inside the
        // implicit contexts created by layout.
        if (RE_OPENBRACKET.test(token)) {
            const level = state.contexts.filter(isBracket).length;
            if (level <= 6) style = `${style}-${level}`;

            let functionName = null;
            if (token === '(' && state.lastTokens.length > 1) {
                const nextToLast = state.lastTokens[state.lastTokens.length - 2];
                if (RE_VARID.test(nextToLast) || RE_CONID.test(nextToLast)) {
                    functionName = nextToLast;
                }
            }

            let newColumn = 0;
            if (state.contexts.length > 0) {
                newColumn = state.contexts[state.contexts.length - 1].column + config.indentUnit;
            }
            state.contexts.push({
                value: token,
                column: newColumn,
                ln: state.line,
                ch: column,
                functionName,
                argIndex: 0
            });
        }

        return isLayout ? `${style} layout` : style;
    }

    return {
        startState: () => {
            return {
                func: normal,
                commentLevel: 0,
                continued: false,
                contexts: [],
                lastTokens: [],
                line: 0
            };
        },
        copyState: state => {
            return {
                func: state.func,
                commentLevel: state.commentLevel,
                continued: state.continued,
                contexts: state.contexts.map(ctx => {
                    return {
                        value: ctx.value,
                        column: ctx.column,
                        ln: ctx.ln,
                        ch: ctx.ch,
                        functionName: ctx.functionName,
                        argIndex: ctx.argIndex || 0
                    };
                }),
                lastTokens: state.lastTokens.map(t => t),
                line: state.line
            };
        },
        token: (stream, state) => {
            const column = stream.column();
            let style = parseToken(stream, state);

            // Ignore whitespaces and comments for layout purposes.
            if (style !== null && style !== 'comment' && style !== 'meta') {
                style = updateLayout(stream.current(), column, style, state);
            }

            if (stream.eol()) state.line++;
            return style;
        },
        blankLine: state => {
            state.line++;
        },
        indent: (state, textAfter) => {
            if (state.commentLevel > 0 || state.contexts.length < 1) return CodeMirror.Pass;

            // Find the top layout level.  If the next token closes a layout, then
            // this is the layout above the one that's closed, but an extra indent is
            // needed.  Otherwise, it's the top of the stack.
            let topLayout = state.contexts.length - 1;
            const token = textAfter.match(/^(in\b|where\b|[,)\]}])/);
            if (token && token[0] === ',') {
                while (topLayout > 0 && !isBracket(state.contexts[topLayout])) {
                    --topLayout;
                }
            } else if (token && token[0] === 'where') {
                while (topLayout > 0 && ['let', 'of', 'do', 'case'].indexOf(state.contexts[topLayout].value) >= 0) {
                    --topLayout;
                }
            } else if (token && state.contexts.findIndex(ctx => ctx.value === opening(token[0])) >= 1) {
                while (state.contexts[topLayout].value !== opening(token[0])) {
                    --topLayout;
                }
                --topLayout;
            }

            const layoutIndent = state.contexts[topLayout].column || 0;

            if (/^(where|[|])/.test(textAfter)) return layoutIndent + Math.ceil(config.indentUnit / 2);
            else if (state.continued || RE_ELECTRIC_START.test(textAfter)) return layoutIndent + config.indentUnit;
            else return layoutIndent;
        },
        electricInput: RE_ELECTRIC_INPUT,
        blockCommentStart: '{-',
        blockCommentEnd: '-}',
        lineComment: '--'
    };
});
<|endoftext|>


<commit_before>function initialize_records_form() {
    $('#format_lbl').hide();
    $('#diskDiameters_lbl').hide();
    $('#reelDiameters_lbl').hide();
    $('#mediaDiameters_lbl').hide();
    $('#tapeThickness_lbl').hide();
    $('#trackTypes_lbl').hide();
    $('#cassetteSize_lbl').hide();
    $("#formatVersion_lbl").hide();
    $('#bases_lbl').hide();
    $('#recordingSpeed_lbl').hide();

    if (selectedMediaType)
        $('.new #mediaType option[value="' + selectedMediaType + '"]').attr("selected", "selected");
    $.mask.definitions['y'] = '[1-2,x]';
    $.mask.definitions['m'] = '[0-1,x]';
    $.mask.definitions['d'] = '[0-3,x]';
    $.mask.definitions['g'] = '[0-9,x]';
    $("#creationDate, #contentDate").mask("yggg-mg-dg", {optional: true});
    updateProjects();
    updateFormat();
    onChangeMediaType();
    showUpdateFields();
    saveBulkEdit();
    closeBtn();
    uniqueIdCheck();
    $("input,textarea,select").keypress(function () {
        changes = true;
    });
    $("select").click(function () {
        if ($(this).attr('id') != 'mediaType') {
            changes = true;
        } else {
            chages = false;
        }
    });

    window.onbeforeunload = function () {
        if (changes)
        {
            return 'The changes are not saved and will be lost.';
        }
    }
    $('form').submit(function () {
        changes = false;
        return true; // return false to cancel form action
    });
}

function uniqueIdCheck() {
    $('#uniqueId').blur(function () {
        var id = $('#uniqueId').val();
        $.ajax({
            type: "POST",
            url: baseUrl + 'checkUniqueId',
            data: {unique_id: id},
            dataType: 'json',
            success: function (response) {
                if (response.success == 'false') {
                    $('#uniqueId_lbl .has-error').text('hello wrong....');
                }
                console.log('almost done wd every thng....');
            }
        });
    });
}
function updateFormat() {
    var selfObj = this;
    selfObj.ajaxCall = false;
    /// call to get base dropdown options
//    $('#processing').html(' Processing please wait...');
    if (selectedFormat) {
        url = baseUrl + 'getFormat/' + $("#mediaType").val() + '/' + selectedFormat;
    } else {
        url = baseUrl + 'getFormat/' + $("#mediaType").val();
    }
    $.ajax({
        type: "GET",
        url: url,
        success: function (response) {
            if (response != "") {
                $('#format_lbl').show();
                $("#format").html(response);
                $("#format").change();
                $('#processing').hide();
                $('#fieldsPanel').show();
            }
        }

    }); // Ajax Call
}

function showUpdateFields() {
    $('#format').change(function () {
        var showDiskDiameter = [16, 17, 18, 19, 20, 28];
        var showMediaDiameter = [1, 2, 3, 4, 5, 24];
        var showTapeThickness = [1, 2, 3, 4, 5];
        var showTrackType = [1, 2, 3, 4, 5];
        var showCassetteSize = [59, 60, 33, 34, 35, 43, 44, 46, 47, 48, 52, 53, 54, 55, 57];
        var hideRecordingSpeedFormat = [37, 39, 40, 41];
        var hideIfFormat = [24, 25, 26];
        var showSideIfFormat = [1, 10, 11, 13, 14, 16, 17, 18, 19, 20, 27, 28];
        var showNoiceRedIfFormat = [1, 2, 4, 5, 6, 7, 10, 13, 14, 27];
        var hideBaseIfFormat = [3, 4, 5];

        if (jQuery.inArray(parseInt($(this).val()), showDiskDiameter) >= 0) {
            $('#diskDiameters_lbl').show();
        } else {
            $('#diskDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showMediaDiameter) >= 0) {
            $('#mediaDiameters_lbl').show();
        } else {
            $('#mediaDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTapeThickness) >= 0) {
            $('#tapeThickness_lbl').show();
        } else {
            $('#tapeThickness_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTrackType) >= 0) {
            $('#trackTypes_lbl').show();
        } else {
            $('#trackTypes_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showCassetteSize) >= 0) {
            $('#cassetteSize_lbl').show();
        } else {
            $('#cassetteSize_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), hideIfFormat) >= 0) {
            $('#slides_lbl, #monoStereo_lbl').hide();
        } else {
            $('#slides_lbl, #monoStereo_lbl').show();
        }
        if (jQuery.inArray(parseInt($(this).val()), showSideIfFormat) >= 0) {
            $('#slides_lbl').show();
        } else {
            $('#slides_lbl').hide();
        }
        if (jQuery.inArray(parseInt($(this).val()), showNoiceRedIfFormat) >= 0) {
            $('#noiceReduction_lbl').show();
        } else {
            $('#noiceReduction_lbl').hide();
        }
        if ($(this).val()) {
            if (jQuery.inArray(parseInt($(this).val()), hideBaseIfFormat) >= 0) {
                $("#bases_lbl").hide();
            } else {
                /// call to get base dropdown options
                $.ajax({
                    type: "GET",
                    url: baseUrl + 'getBase/' + $(this).val(),
                    success: function (response) {
                        if (response != "") {
                            $("#bases_lbl").show();
                            $("#bases").html(response);
                        } else {
                            $("#bases_lbl").hide();
                        }
                    }

                }); // Ajax Call
            }
            /// call to get reel diameters dropdown options
            if (selectedRD) {
                RDurl = baseUrl + 'getReelDiameter/' + $(this).val() + '/' + $("#mediaType").val() + '/' + selectedRD;
            } else {
                RDurl = baseUrl + 'getReelDiameter/' + $(this).val() + '/' + $("#mediaType").val();
            }
            $.ajax({
                type: "GET",
                url: RDurl,
                success: function (response) {
                    if (response != "") {
                        $("#reelDiameters_lbl").show();
                        $("#reelDiameters").html(response);
                    } else {
                        $("#reelDiameters_lbl").hide();
                    }
                }

            }); // Ajax Call
            if (jQuery.inArray(parseInt($(this).val()), hideRecordingSpeedFormat) >= 0) {
                $('#recordingSpeed_lbl').hide();
            } else {
                $('#recordingSpeed_lbl').show();
                /// call to get recording speed dropdown options
                if (selectedRS) {
                    url = baseUrl + 'getRecordingSpeed/' + $(this).val() + '/' + $("#mediaType").val() + '/' + selectedRS;
                } else {
                    url = baseUrl + 'getRecordingSpeed/' + $(this).val() + '/' + $("#mediaType").val();
                }
                $.ajax({
                    type: "GET",
                    url: url,
                    success: function (response) {
                        if (response != "") {
                            $("#recordingSpeed_lbl").show();
                            $("#recordingSpeed").html(response);
                        } else {
                            $("#recordingSpeed_lbl").hide();
                        }
                    }
                }); // Ajax Call
            }
            /// call to get formatversion dropdown options
            if (selectedFormatVersion) {
                formatVersiourl = baseUrl + 'getFormatVersion/' + $(this).val() + '/' + selectedFormatVersion;
            } else {
                formatVersiourl = baseUrl + 'getFormatVersion/' + $(this).val();
            }
            $.ajax({
                type: "GET",
                url: formatVersiourl,
                success: function (response) {
                    if (response != "") {
                        $("#formatVersion_lbl").show();
                        $("#formatVersion").html(response);
                    } else {
                        $("#formatVersion_lbl").hide();
                    }
                }

            }); // Ajax Call
        } else {
            $('#diskDiameters_lbl').hide();
            $('#reelDiameters_lbl').hide();
            $('#mediaDiameters_lbl').hide();
            $('#tapeThickness_lbl').hide();
            $('#trackTypes_lbl').hide();
            $('#cassetteSize_lbl').hide();
            $("#formatVersion_lbl").hide();
            $('#bases_lbl').hide();
            $('#recordingSpeed_lbl').hide();
        }
    });

}

function onChangeMediaType() {
    $(".new #mediaType").change(function () {
        if ($(this).val() == 3) {
            $('#fieldsPanel').hide();
            $('#processing').show();
            window.location.href = baseUrl + 'video/new';
        } else if ($(this).val() == 2) {
            $('#fieldsPanel').hide();
            $('#processing').show();
            window.location.href = baseUrl + 'film/new';
        } else if ($(this).val() == 1) {
            $('#fieldsPanel').hide();
            $('#processing').show();
            window.location.href = baseUrl + 'audio/new';
        }
    });
}

function saveBulkEdit() {
    $("#submitBulkEdit").click(function () {
        data = $('#frmBulkEdit').serialize();
        $(document).ajaxStart(function () {
            $("#frmBulkEdit").hide();
            $('#editProcessing').show();
            $('#editProcessing').css('color', 'black');
            $('#editProcessing').html(' Processing please wait...');
        });
        $.ajax({
            type: "POST",
            url: bulkEdit,
            data: data,
            dataType: 'json',
            success: function (response) {
                if (response.success === true) {
                    window.location.reload();
                }
            }
        }); // Ajax Call
    });
}

function closeBtn() {
    $(".bulkEditCloseBtn").on('click', function () {
        $.modal.close();
        $('#selectAll').prop("checked", false);
        $('input[name=record_checkbox]').each(function () {
            $(this).prop("checked", false);
        });
        $('#records tr').each(function () {
            $(this).removeClass("selected");
        });
        $("#selectedrecords").val('');
        window.location.reload();
    });
}

function updateProjects() {
    if (selectedProject) {
        urlProjects = baseUrl + 'getAllProjects/' + selectedProject;
    } else {
        urlProjects = baseUrl + 'getAllProjects';
    }
    $.ajax({
        type: "GET",
        url: urlProjects,
        success: function (response) {
            if (response != "") {
                $("#project").html(response);
            }
        }
    }); // Ajax Call
}<commit_msg>debugging unique id field<commit_after>function initialize_records_form() {
    $('#format_lbl').hide();
    $('#diskDiameters_lbl').hide();
    $('#reelDiameters_lbl').hide();
    $('#mediaDiameters_lbl').hide();
    $('#tapeThickness_lbl').hide();
    $('#trackTypes_lbl').hide();
    $('#cassetteSize_lbl').hide();
    $("#formatVersion_lbl").hide();
    $('#bases_lbl').hide();
    $('#recordingSpeed_lbl').hide();

    if (selectedMediaType)
        $('.new #mediaType option[value="' + selectedMediaType + '"]').attr("selected", "selected");
    $.mask.definitions['y'] = '[1-2,x]';
    $.mask.definitions['m'] = '[0-1,x]';
    $.mask.definitions['d'] = '[0-3,x]';
    $.mask.definitions['g'] = '[0-9,x]';
    $("#creationDate, #contentDate").mask("yggg-mg-dg", {optional: true});
    updateProjects();
    updateFormat();
    onChangeMediaType();
    showUpdateFields();
    saveBulkEdit();
    closeBtn();
    uniqueIdCheck();
    $("input,textarea,select").keypress(function () {
        changes = true;
    });
    $("select").click(function () {
        if ($(this).attr('id') != 'mediaType') {
            changes = true;
        } else {
            chages = false;
        }
    });

    window.onbeforeunload = function () {
        if (changes)
        {
            return 'The changes are not saved and will be lost.';
        }
    }
    $('form').submit(function () {
        changes = false;
        return true; // return false to cancel form action
    });
}

function uniqueIdCheck() {
    $('#uniqueId').blur(function () {
        var id = $('#uniqueId').val();
        $.ajax({
            type: "POST",
            url: baseUrl + 'checkUniqueId',
            data: {unique_id: id},
            dataType: 'json',
            success: function (response) {
                if (response.success == 'false') {
                    $('#uniqueId_lbl .has-error').text('Unique id is required');
                    $('#uniqueId').val('');
                }else{
                    $('#uniqueId_lbl .has-error').text('');
                }
                console.log('almost done wd every thng....');
            }
        });
    });
}
function updateFormat() {
    var selfObj = this;
    selfObj.ajaxCall = false;
    /// call to get base dropdown options
//    $('#processing').html(' Processing please wait...');
    if (selectedFormat) {
        url = baseUrl + 'getFormat/' + $("#mediaType").val() + '/' + selectedFormat;
    } else {
        url = baseUrl + 'getFormat/' + $("#mediaType").val();
    }
    $.ajax({
        type: "GET",
        url: url,
        success: function (response) {
            if (response != "") {
                $('#format_lbl').show();
                $("#format").html(response);
                $("#format").change();
                $('#processing').hide();
                $('#fieldsPanel').show();
            }
        }

    }); // Ajax Call
}

function showUpdateFields() {
    $('#format').change(function () {
        var showDiskDiameter = [16, 17, 18, 19, 20, 28];
        var showMediaDiameter = [1, 2, 3, 4, 5, 24];
        var showTapeThickness = [1, 2, 3, 4, 5];
        var showTrackType = [1, 2, 3, 4, 5];
        var showCassetteSize = [59, 60, 33, 34, 35, 43, 44, 46, 47, 48, 52, 53, 54, 55, 57];
        var hideRecordingSpeedFormat = [37, 39, 40, 41];
        var hideIfFormat = [24, 25, 26];
        var showSideIfFormat = [1, 10, 11, 13, 14, 16, 17, 18, 19, 20, 27, 28];
        var showNoiceRedIfFormat = [1, 2, 4, 5, 6, 7, 10, 13, 14, 27];
        var hideBaseIfFormat = [3, 4, 5];

        if (jQuery.inArray(parseInt($(this).val()), showDiskDiameter) >= 0) {
            $('#diskDiameters_lbl').show();
        } else {
            $('#diskDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showMediaDiameter) >= 0) {
            $('#mediaDiameters_lbl').show();
        } else {
            $('#mediaDiameters_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTapeThickness) >= 0) {
            $('#tapeThickness_lbl').show();
        } else {
            $('#tapeThickness_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showTrackType) >= 0) {
            $('#trackTypes_lbl').show();
        } else {
            $('#trackTypes_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), showCassetteSize) >= 0) {
            $('#cassetteSize_lbl').show();
        } else {
            $('#cassetteSize_lbl').hide();
        }

        if (jQuery.inArray(parseInt($(this).val()), hideIfFormat) >= 0) {
            $('#slides_lbl, #monoStereo_lbl').hide();
        } else {
            $('#slides_lbl, #monoStereo_lbl').show();
        }
        if (jQuery.inArray(parseInt($(this).val()), showSideIfFormat) >= 0) {
            $('#slides_lbl').show();
        } else {
            $('#slides_lbl').hide();
        }
        if (jQuery.inArray(parseInt($(this).val()), showNoiceRedIfFormat) >= 0) {
            $('#noiceReduction_lbl').show();
        } else {
            $('#noiceReduction_lbl').hide();
        }
        if ($(this).val()) {
            if (jQuery.inArray(parseInt($(this).val()), hideBaseIfFormat) >= 0) {
                $("#bases_lbl").hide();
            } else {
                /// call to get base dropdown options
                $.ajax({
                    type: "GET",
                    url: baseUrl + 'getBase/' + $(this).val(),
                    success: function (response) {
                        if (response != "") {
                            $("#bases_lbl").show();
                            $("#bases").html(response);
                        } else {
                            $("#bases_lbl").hide();
                        }
                    }

                }); // Ajax Call
            }
            /// call to get reel diameters dropdown options
            if (selectedRD) {
                RDurl = baseUrl + 'getReelDiameter/' + $(this).val() + '/' + $("#mediaType").val() + '/' + selectedRD;
            } else {
                RDurl = baseUrl + 'getReelDiameter/' + $(this).val() + '/' + $("#mediaType").val();
            }
            $.ajax({
                type: "GET",
                url: RDurl,
                success: function (response) {
                    if (response != "") {
                        $("#reelDiameters_lbl").show();
                        $("#reelDiameters").html(response);
                    } else {
                        $("#reelDiameters_lbl").hide();
                    }
                }

            }); // Ajax Call
            if (jQuery.inArray(parseInt($(this).val()), hideRecordingSpeedFormat) >= 0) {
                $('#recordingSpeed_lbl').hide();
            } else {
                $('#recordingSpeed_lbl').show();
                /// call to get recording speed dropdown options
                if (selectedRS) {
                    url = baseUrl + 'getRecordingSpeed/' + $(this).val() + '/' + $("#mediaType").val() + '/' + selectedRS;
                } else {
                    url = baseUrl + 'getRecordingSpeed/' + $(this).val() + '/' + $("#mediaType").val();
                }
                $.ajax({
                    type: "GET",
                    url: url,
                    success: function (response) {
                        if (response != "") {
                            $("#recordingSpeed_lbl").show();
                            $("#recordingSpeed").html(response);
                        } else {
                            $("#recordingSpeed_lbl").hide();
                        }
                    }
                }); // Ajax Call
            }
            /// call to get formatversion dropdown options
            if (selectedFormatVersion) {
                formatVersiourl = baseUrl + 'getFormatVersion/' + $(this).val() + '/' + selectedFormatVersion;
            } else {
                formatVersiourl = baseUrl + 'getFormatVersion/' + $(this).val();
            }
            $.ajax({
                type: "GET",
                url: formatVersiourl,
                success: function (response) {
                    if (response != "") {
                        $("#formatVersion_lbl").show();
                        $("#formatVersion").html(response);
                    } else {
                        $("#formatVersion_lbl").hide();
                    }
                }

            }); // Ajax Call
        } else {
            $('#diskDiameters_lbl').hide();
            $('#reelDiameters_lbl').hide();
            $('#mediaDiameters_lbl').hide();
            $('#tapeThickness_lbl').hide();
            $('#trackTypes_lbl').hide();
            $('#cassetteSize_lbl').hide();
            $("#formatVersion_lbl").hide();
            $('#bases_lbl').hide();
            $('#recordingSpeed_lbl').hide();
        }
    });

}

function onChangeMediaType() {
    $(".new #mediaType").change(function () {
        if ($(this).val() == 3) {
            $('#fieldsPanel').hide();
            $('#processing').show();
            window.location.href = baseUrl + 'video/new';
        } else if ($(this).val() == 2) {
            $('#fieldsPanel').hide();
            $('#processing').show();
            window.location.href = baseUrl + 'film/new';
        } else if ($(this).val() == 1) {
            $('#fieldsPanel').hide();
            $('#processing').show();
            window.location.href = baseUrl + 'audio/new';
        }
    });
}

function saveBulkEdit() {
    $("#submitBulkEdit").click(function () {
        data = $('#frmBulkEdit').serialize();
        $(document).ajaxStart(function () {
            $("#frmBulkEdit").hide();
            $('#editProcessing').show();
            $('#editProcessing').css('color', 'black');
            $('#editProcessing').html(' Processing please wait...');
        });
        $.ajax({
            type: "POST",
            url: bulkEdit,
            data: data,
            dataType: 'json',
            success: function (response) {
                if (response.success === true) {
                    window.location.reload();
                }
            }
        }); // Ajax Call
    });
}

function closeBtn() {
    $(".bulkEditCloseBtn").on('click', function () {
        $.modal.close();
        $('#selectAll').prop("checked", false);
        $('input[name=record_checkbox]').each(function () {
            $(this).prop("checked", false);
        });
        $('#records tr').each(function () {
            $(this).removeClass("selected");
        });
        $("#selectedrecords").val('');
        window.location.reload();
    });
}

function updateProjects() {
    if (selectedProject) {
        urlProjects = baseUrl + 'getAllProjects/' + selectedProject;
    } else {
        urlProjects = baseUrl + 'getAllProjects';
    }
    $.ajax({
        type: "GET",
        url: urlProjects,
        success: function (response) {
            if (response != "") {
                $("#project").html(response);
            }
        }
    }); // Ajax Call
}<|endoftext|>


<commit_before>/*
 * Angular Hammer v2
 *
 * Forked from https://github.com/randallb/angular-hammer
 * Updated to support https://github.com/EightMedia/hammer.js
 *
 * Within an Angular.js application, allows you to specify custom behaviour on Hammer.js touch events.
 *
 * Usage, currently as attribute only:
 *
 *    hm-tap="{expression}"
 *
 * You can change the default settings for the instance by adding a second attribute with options:
 *
 *    hm-options="{drag: false, transform: false}"
 *
 * Include this file, and add `hmTouchevents` to your app's dependencies.
 *
 * Requires Hammer.js, tested with `v1.0.1 - 2013-02-26`.
 *
 */

var hmTouchevents = angular.module('hmTouchevents', []),
    hmGestures = ['hmHold:hold',
                  'hmTap:tap',
                  'hmDoubletap:doubletap',
                  'hmDrag:drag',
                  'hmDragup:dragup',
                  'hmDragdown:dragedown',
                  'hmDragleft:dragleft',
                  'hmDragright:dragright',
                  'hmSwipe:swipe',
                  'hmSwipeup:swipeup',
                  'hmSwipedown:swipedown',
                  'hmSwipeleft:swipeleft',
                  'hmSwiperight:swiperight',
                  'hmTransform:transform',
                  'hmRotate:rotate',
                  'hmPinch:pinch',
                  'hmPinchin:pinchin',
                  'hmPinchout:pinchout',
                  'hmTouch:touch',
                  'hmRelease:release'];

angular.forEach(hmGestures, function(name){
  var directive = name.split(':'),
      directiveName = directive[0],
      eventName = directive[1];
  hmTouchevents.directive(directiveName, ['$parse', function($parse){
    return {
      restrict: 'A',
      link: function(scope, element, attr) {
        var fn = $parse(attr[directiveName]),
            opts = $parse(attr['hmOptions'])(scope, {}),
            elm = element[0],
            ngElm = angular.element(elm),
            hammer = ngElm.data('hammer');
        if (!hammer) {
          hammer = Hammer(elm, opts);
          ngElm.data('hammer', hammer);
        }
        hammer.on(eventName, function(event){
          scope.$apply(function() {
            fn(scope, {$event: event});
          });
        });
      }
    };
  }]);
});
<commit_msg>revert back to storing instance on scope scope: true creates a shared directive scope<commit_after>/*
 * Angular Hammer v2
 *
 * Forked from https://github.com/randallb/angular-hammer
 * Updated to support https://github.com/EightMedia/hammer.js
 *
 * Within an Angular.js application, allows you to specify custom behaviour on Hammer.js touch events.
 *
 * Usage, currently as attribute only:
 *
 *    hm-tap="{expression}"
 *
 * You can change the default settings for the instance by adding a second attribute with options:
 *
 *    hm-options="{drag: false, transform: false}"
 *
 * Include this file, and add `hmTouchevents` to your app's dependencies.
 *
 * Requires Hammer.js, tested with `v1.0.1 - 2013-02-26`.
 *
 */

var hmTouchevents = angular.module('hmTouchevents', []),
    hmGestures = ['hmHold:hold',
                  'hmTap:tap',
                  'hmDoubletap:doubletap',
                  'hmDrag:drag',
                  'hmDragup:dragup',
                  'hmDragdown:dragedown',
                  'hmDragleft:dragleft',
                  'hmDragright:dragright',
                  'hmSwipe:swipe',
                  'hmSwipeup:swipeup',
                  'hmSwipedown:swipedown',
                  'hmSwipeleft:swipeleft',
                  'hmSwiperight:swiperight',
                  'hmTransform:transform',
                  'hmRotate:rotate',
                  'hmPinch:pinch',
                  'hmPinchin:pinchin',
                  'hmPinchout:pinchout',
                  'hmTouch:touch',
                  'hmRelease:release'];

angular.forEach(hmGestures, function(name){
  var directive = name.split(':'),
      directiveName = directive[0],
      eventName = directive[1];
  hmTouchevents.directive(directiveName, ['$parse', function($parse){
    return {
      restrict: 'A',
      scope: true,
      link: function(scope, element, attr) {
          var fn = $parse(attr[directiveName]),
            opts = $parse(attr['hmOptions'])(scope, {});
        scope.hammer = scope.hammer || Hammer(element[0], opts);
        scope.hammer.on(eventName, function(event){
          scope.$apply(function() {
            fn(scope, {$event: event});
          });
        });
      }
    };
  }]);
});
<|endoftext|>


<commit_before>/**
 * Created by anonymous on 09/12/15 13:11.
 */

(function() {
    'use strict';

    angular
        .module('dashboard')
        .config(config);

    config.$inject = ['$stateProvider', '$urlRouterProvider'];

    /* @ngInject */
    function config($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/');

        $stateProvider
            .state('dashboard', {
                abstract: true,
                url     : '/dashboard',
                views   : {
                    'layout@'         : {
                        templateUrl : layout('dashboard.simple'),
                        controller  : 'DashboardController',
                        controllerAs: 'dashboard'
                    },
                    'header@dashboard': {
                        templateUrl : view('dashboard.header'),
                        controller  : 'DashboardHeaderController',
                        controllerAs: 'header'
                    },
                    'left@dashboard'  : {
                        templateUrl : view('dashboard.left'),
                        controller  : 'DashboardLeftController',
                        controllerAs: 'left'
                    },
                    'right@dashboard' : {
                        templateUrl : view('dashboard.right'),
                        controller  : 'DashboardRightController',
                        controllerAs: 'right'
                    },
                    'footer@dashboard': {
                        templateUrl : view('dashboard.footer'),
                        controller  : 'DashboardFooterController',
                        controllerAs: 'footer'
                    },
                    'main@dashboard'  : {}
                }
            })
            .state('dashboard.home', {
                url  : '/',
                data : { pageName: 'Overview' },
                views: {
                    'main@dashboard': {
                        templateUrl : view('dashboard.home'),
                        controller  : 'DashboardHomeController',
                        controllerAs: 'home'
                    }
                }
            });

        function view(viewName) {
            if (viewName !== "") {
                return './views/app/' + appName(viewName) + '/' + fileDir(viewName) + '/' + fileName(viewName) + '.html';
            } else {
                return './views/app/app/home/home.html';
            }
        }

        function layout(viewName) {
            if (viewName !== "") {
                return './views/layouts/' + appName(viewName) + '/' + fileDir(viewName) + '/' + fileName(viewName) + '.html';
            } else {
                return './views/app/app/home/home.html';
            }

        }

        function appName(v) {
            if (v.split(".")[0]) {
                return v.split(".")[0];
            } else {
                return 'app';
            }
        }

        function fileDir(v) {
            if (v.split(".")[1]) {
                return v.split(".")[1];
            } else if (!v.split(".")[0]) {
                return v;
            } else {
                return 'home';
            }
        }

        function fileName(v) {
            if (v.split(".")[2]) {
                return v.split(".")[2];
            } else if (!v.split(".")[2]) {
                if (v.split(".")[1]) {
                    return v.split(".")[1];
                }
            } else {
                return 'home';
            }
        }
    }

})();

<commit_msg>Update routes.js<commit_after>/**
 * Created by anonymous on 09/12/15 13:11.
 */

(function() {
    'use strict';

    angular
        .module('dashboard')
        .config(dashboardRouter);

    dashboardRouter.$inject = ['$stateProvider', '$urlRouterProvider'];

    /* @ngInject */
    function dashboardRouter($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise('/');

        $stateProvider
            .state('dashboard', {
                abstract: true,
                url     : '/dashboard',
                views   : {
                    'layout@'         : {
                        templateUrl : layout('dashboard.simple'),
                        controller  : 'DashboardController',
                        controllerAs: 'dashboard'
                    },
                    'header@dashboard': {
                        templateUrl : view('dashboard.header'),
                        controller  : 'DashboardHeaderController',
                        controllerAs: 'header'
                    },
                    'left@dashboard'  : {
                        templateUrl : view('dashboard.left'),
                        controller  : 'DashboardLeftController',
                        controllerAs: 'left'
                    },
                    'right@dashboard' : {
                        templateUrl : view('dashboard.right'),
                        controller  : 'DashboardRightController',
                        controllerAs: 'right'
                    },
                    'footer@dashboard': {
                        templateUrl : view('dashboard.footer'),
                        controller  : 'DashboardFooterController',
                        controllerAs: 'footer'
                    },
                    'main@dashboard'  : {}
                }
            })
            .state('dashboard.home', {
                url  : '/',
                data : {pageName: 'Overview'},
                views: {
                    'main@dashboard': {
                        templateUrl : view('dashboard.home'),
                        controller  : 'DashboardHomeController',
                        controllerAs: 'home'
                    }
                }
            });

        function view(viewName) {
            if (viewName !== '') {
                return './views/app/' + appName(viewName) + '/' + fileDir(viewName) + '/' + fileName(viewName) + '.html';
            } else {
                return './views/app/app/home/home.html';
            }
        }

        function layout(viewName) {
            if (viewName !== '') {
                return './views/layouts/' + appName(viewName) + '/' + fileDir(viewName) + '/' + fileName(viewName) + '.html';
            } else {
                return './views/app/app/home/home.html';
            }

        }

        function appName(v) {
            if (v.split('.')[0]) {
                return v.split('.')[0];
            } else {
                return 'app';
            }
        }

        function fileDir(v) {
            if (v.split('.')[1]) {
                return v.split('.')[1];
            } else if (!v.split('.')[0]) {
                return v;
            } else {
                return 'home';
            }
        }

        function fileName(v) {
            if (v.split('.')[2]) {
                return v.split('.')[2];
            } else if (!v.split('.')[2]) {
                if (v.split('.')[1]) {
                    return v.split('.')[1];
                }
            } else {
                return 'home';
            }
        }
    }

})();

<|endoftext|>


<commit_before>/**********************
* The MIT License (MIT)
*
* Copyright (c) 2014 David Arvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
**********************/

(function (name, definition) {
    if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
        module.exports = definition();
    } else if (typeof define === 'function' && typeof define.amd === 'object') {
        define(definition);
    } else {
        this[name] = definition();
    }
})('AnimationLoop', function () {

function AnimationLoop (options) {
    this.startTime = null;
    this.animations = this.constructor.createAnimationArray(options);
    this.remaining = this.animations.length;
    this.complete = false;
}

AnimationLoop.create = function (options) {
    if (typeof options !== 'function' && typeof options !== 'object' && !Array.isArray(options)) {
        throw new Error('Options to AnimationLoop are not of a supported type.');
    }

    if (Array.isArray(options)) {
        var optionsOK = options.every(function (anim) {
            return typeof anim === 'function' || (typeof anim === 'object' && !Array.isArray(anim));
        });

        if (!optionsOK) {
            throw new Error('Array options to AnimationLoop are not of a supported type.');
        }
    }

    return new this(options).start();
};

AnimationLoop.createAnimationArray = function createAnimationArray (options) {
    if (Array.isArray(options)) {
        return options.map(createAnimationArray);
    }

    if (typeof options === 'object') {
        return [options];
    }

    if (typeof options === 'function') {
        return [{ render: options }];
    }
};

AnimationLoop.raf = (function() {
    var raf = window.requestAnimationFrame ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame;

    return function (callback) {
      return raf(callback);
    };
})();

AnimationLoop.caf = (function() {
    var caf = window.cancelAnimationFrame ||
              window.cancelRequestAnimationFrame ||
              window.webkitCancelRequestAnimationFrame ||
              window.mozCancelRequestAnimationFrame;

    return function (id) {
      return caf(id);
    };
})();

AnimationLoop.prototype = {
    constructor: AnimationLoop,

    start: function () {
        this.rafId = this.constructor.raf(this.cycle.bind(this));
        return this;
    },

    cancel: function () {
        this.constructor.caf(this.rafId);
        return this;
    },

    cycle: function (now) {
        var animations = this.animations.slice();
        var startTime, lastTime;

        if (!animations.length) {
            this.complete = true;
            return;
        }

        if (!this.startTime) {
            this.startTime = startTime = now;
        }

        if (!this.lastTime) {
            this.lastTime = now;
        }

        lastTime = this.lastTime;

        var timing = {
            startTime: startTime,
            lastTime: lastTime,
            animTime: lastTime - startTime,
            now: now,
            deltaT: now - lastTime,
        };

        animations.forEach(function (anim) {
            var pct;

            if (anim.duration) {
                timing.duration = anim.duration;
                pct = Math.max(0, Math.min(1, timing.animTime / timing.duration));
                anim.pct = timing.pct = pct;
                anim.lastPct = timing.lastPct = timing.lastPct || pct;
            } else {
                timing.duration = null;
                timing.pct = null;
                timing.lastPct = null;
            }

            if (typeof anim.before === 'function') {
                anim.running = anim.before(timing);
            }
        }, this);

        this.animations = animations.filter(function (anim) {
            var pct = anim.pct;

            if (anim.running === false) {
                this.remaining--;
                return false;
            }

            timing.duration = anim.duration;
            // these should be set on anim by now if anim.duration exists
            timing.pct = pct;
            timing.lastPct = anim.lastPct;

            var running = anim.render(timing);

            if (running === false || anim.pct === 1) {
                if (typeof anim.done === 'function') {
                    anim.done();
                }

                this.remaining--;
                return false;
            } else if (running === 'cancel') {
                this.remaining--;
                return false;
            }

            return true;
        }, this);

        this.rafId = this.constructor.raf(this.cycle.bind(this));
    },
};

return AnimationLoop;

});
<commit_msg>Make option-parsing functions private<commit_after>/**********************
* The MIT License (MIT)
*
* Copyright (c) 2014 David Arvelo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
**********************/

(function (name, definition) {
    if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
        module.exports = definition();
    } else if (typeof define === 'function' && typeof define.amd === 'object') {
        define(definition);
    } else {
        this[name] = definition();
    }
})('AnimationLoop', function () {

function AnimationLoop (options) {
    checkOptions(options);

    this.animations = createAnimationArray(options);
    this.startTime = null;
    this.remaining = this.animations.length;
    this.complete = false;
}

AnimationLoop.create = function (options) {
    return new this(options).start();
};

function checkOptions (options) {
    if (typeof options !== 'function' && typeof options !== 'object' && !Array.isArray(options)) {
        throw new Error('Options to AnimationLoop are not of a supported type.');
    }

    if (Array.isArray(options)) {
        var optionsOK = options.every(function (anim) {
            return typeof anim === 'function' || (typeof anim === 'object' && !Array.isArray(anim));
        });

        if (!optionsOK) {
            throw new Error('Array options to AnimationLoop are not of a supported type.');
        }
    }
}

function createAnimationArray (options) {
    if (Array.isArray(options)) {
        return options.map(createAnimationArray);
    }

    if (typeof options === 'object') {
        return [options];
    }

    if (typeof options === 'function') {
        return [{ render: options }];
    }
}

AnimationLoop.raf = (function() {
    var raf = window.requestAnimationFrame ||
              window.webkitRequestAnimationFrame ||
              window.mozRequestAnimationFrame;

    return function (callback) {
      return raf(callback);
    };
})();

AnimationLoop.caf = (function() {
    var caf = window.cancelAnimationFrame ||
              window.cancelRequestAnimationFrame ||
              window.webkitCancelRequestAnimationFrame ||
              window.mozCancelRequestAnimationFrame;

    return function (id) {
      return caf(id);
    };
})();

AnimationLoop.prototype = {
    constructor: AnimationLoop,

    start: function () {
        this.rafId = this.constructor.raf(this.cycle.bind(this));
        return this;
    },

    cancel: function () {
        this.constructor.caf(this.rafId);
        return this;
    },

    cycle: function (now) {
        var animations = this.animations.slice();
        var startTime, lastTime;

        if (!animations.length) {
            this.complete = true;
            return;
        }

        if (!this.startTime) {
            this.startTime = startTime = now;
        }

        if (!this.lastTime) {
            this.lastTime = now;
        }

        lastTime = this.lastTime;

        var timing = {
            startTime: startTime,
            lastTime: lastTime,
            animTime: lastTime - startTime,
            now: now,
            deltaT: now - lastTime,
        };

        animations.forEach(function (anim) {
            var pct;

            if (anim.duration) {
                timing.duration = anim.duration;
                pct = Math.max(0, Math.min(1, timing.animTime / timing.duration));
                anim.pct = timing.pct = pct;
                anim.lastPct = timing.lastPct = timing.lastPct || pct;
            } else {
                timing.duration = null;
                timing.pct = null;
                timing.lastPct = null;
            }

            if (typeof anim.before === 'function') {
                anim.running = anim.before(timing);
            }
        }, this);

        this.animations = animations.filter(function (anim) {
            var pct = anim.pct;

            if (anim.running === false) {
                this.remaining--;
                return false;
            }

            timing.duration = anim.duration;
            // these should be set on anim by now if anim.duration exists
            timing.pct = pct;
            timing.lastPct = anim.lastPct;

            var running = anim.render(timing);

            if (running === false || anim.pct === 1) {
                if (typeof anim.done === 'function') {
                    anim.done();
                }

                this.remaining--;
                return false;
            } else if (running === 'cancel') {
                this.remaining--;
                return false;
            }

            return true;
        }, this);

        this.rafId = this.constructor.raf(this.cycle.bind(this));
    },
};

return AnimationLoop;

});
<|endoftext|>


<commit_before>/* jshint node: true */
'use strict';

var mbus = require('mbus');

// define some state mappings to simplify the events we generate
var stateMappings = {
  completed: 'connected'
};

// define the events that we need to watch for peer connection
// state changes
var peerStateEvents = [
  'signalingstatechange',
  'iceconnectionstatechange',
];

/**
  ### rtc-tools/monitor

  ```
  monitor(pc, targetId, signaller, parentBus) => mbus
  ```

  The monitor is a useful tool for determining the state of `pc` (an
  `RTCPeerConnection`) instance in the context of your application. The
  monitor uses both the `iceConnectionState` information of the peer
  connection and also the various
  [signaller events](https://github.com/rtc-io/rtc-signaller#signaller-events)
  to determine when the connection has been `connected` and when it has
  been `disconnected`.

  A monitor created `mbus` is returned as the result of a
  [couple](https://github.com/rtc-io/rtc#rtccouple) between a local peer
  connection and it's remote counterpart.

**/
module.exports = function(pc, targetId, signaller, parentBus) {
  var monitor = mbus('pc', parentBus);
  var state;

  function checkState() {
    var newState = getMappedState(pc.iceConnectionState);

    // flag the we had a state change
    monitor('change', pc, newState);

    // if the active state has changed, then send the appopriate message
    if (state !== newState) {
      monitor(newState);
      state = newState;
    }
  }

  function handleClose() {
    monitor('closed');
  }

  function handlePeerLeave(peerId) {
    // if the peer leaving is not the peer we are connected to
    // then we aren't interested
    if (peerId !== targetId) {
      return;
    }

    // trigger a closed event
    monitor('closed');
  }

  pc.addEventListener('close', handleClose);
  peerStateEvents.forEach(function(evtName) {
    pc.addEventListener(evtName, checkState);
  });

  monitor.stop = function() {
    pc.removeEventListener('close', handleClose);
    peerStateEvents.forEach(function(evtName) {
      pc.removeEventListener(evtName, checkState);
    });

    // remove the peer:leave listener
    if (signaller && typeof signaller.removeListener == 'function') {
      signaller.removeListener('peer:leave', handlePeerLeave);
    }
  };

  monitor.checkState = checkState;

  // if we haven't been provided a valid peer connection, abort
  if (! pc) {
    return monitor;
  }

  // determine the initial is active state
  state = getMappedState(pc.iceConnectionState);

  // if we've been provided a signaller, then watch for peer:leave events
  if (signaller && typeof signaller.on == 'function') {
    signaller.on('peer:leave', handlePeerLeave);
  }

  return monitor;
};

/* internal helpers */

function getMappedState(state) {
  return stateMappings[state] || state;
}
<commit_msg>Remove the pc namespace for monitor events<commit_after>/* jshint node: true */
'use strict';

var mbus = require('mbus');

// define some state mappings to simplify the events we generate
var stateMappings = {
  completed: 'connected'
};

// define the events that we need to watch for peer connection
// state changes
var peerStateEvents = [
  'signalingstatechange',
  'iceconnectionstatechange',
];

/**
  ### rtc-tools/monitor

  ```
  monitor(pc, targetId, signaller, parentBus) => mbus
  ```

  The monitor is a useful tool for determining the state of `pc` (an
  `RTCPeerConnection`) instance in the context of your application. The
  monitor uses both the `iceConnectionState` information of the peer
  connection and also the various
  [signaller events](https://github.com/rtc-io/rtc-signaller#signaller-events)
  to determine when the connection has been `connected` and when it has
  been `disconnected`.

  A monitor created `mbus` is returned as the result of a
  [couple](https://github.com/rtc-io/rtc#rtccouple) between a local peer
  connection and it's remote counterpart.

**/
module.exports = function(pc, targetId, signaller, parentBus) {
  var monitor = mbus('', parentBus);
  var state;

  function checkState() {
    var newState = getMappedState(pc.iceConnectionState);

    // flag the we had a state change
    monitor('change', pc, newState);

    // if the active state has changed, then send the appopriate message
    if (state !== newState) {
      monitor(newState);
      state = newState;
    }
  }

  function handleClose() {
    monitor('closed');
  }

  function handlePeerLeave(peerId) {
    // if the peer leaving is not the peer we are connected to
    // then we aren't interested
    if (peerId !== targetId) {
      return;
    }

    // trigger a closed event
    monitor('closed');
  }

  pc.addEventListener('close', handleClose);
  peerStateEvents.forEach(function(evtName) {
    pc.addEventListener(evtName, checkState);
  });

  monitor.stop = function() {
    pc.removeEventListener('close', handleClose);
    peerStateEvents.forEach(function(evtName) {
      pc.removeEventListener(evtName, checkState);
    });

    // remove the peer:leave listener
    if (signaller && typeof signaller.removeListener == 'function') {
      signaller.removeListener('peer:leave', handlePeerLeave);
    }
  };

  monitor.checkState = checkState;

  // if we haven't been provided a valid peer connection, abort
  if (! pc) {
    return monitor;
  }

  // determine the initial is active state
  state = getMappedState(pc.iceConnectionState);

  // if we've been provided a signaller, then watch for peer:leave events
  if (signaller && typeof signaller.on == 'function') {
    signaller.on('peer:leave', handlePeerLeave);
  }

  return monitor;
};

/* internal helpers */

function getMappedState(state) {
  return stateMappings[state] || state;
}
<|endoftext|>


<commit_before>define(function(require) {

  var Disposable = require('lavaca/util/Disposable');
  var Config = require('lavaca/util/Config');
  var Device = require('lavaca/env/Device');
  var ga = require('google-analytics');

  var AnalyticsService = Disposable.extend(function AnalyticsService() {
    Disposable.call(this);
    this.appId = Config.get('google_analytics_id');
    this.webId = Config.get('google_analytics_web_id');
    this.isWeb = this.webId.length;

    if (!Device.isCordova() && this.isWeb) {
      ga('create', this.webId);
    }

    document.addEventListener('deviceready', this.init.bind(this), false);
  }, {
    ready: false,
    queue: [],
    isWeb: false,
    //isApp: false, //TODO need to research when Device.isCordova() is valid in Lavaca load flow
    init: function() {
      if (Device.isCordova() && analytics) {
        this.ready = true;
        analytics.startTrackerWithId(this.appId);
        this.processQueue();
        this.isWeb = false;
      }
    },
    trackView: function(screen) {
      if (Device.isCordova()) {
        if (this.ready) {
          analytics.trackView(screen);
        } else {
          this.queue.push({
            action: 'trackView',
            params: [screen]
          });
        }
      } else if (this.isWeb) {
        ga('send', 'pageview', {
          'title': screen
        });
      }
    },
    setUserId: function() {
      throw 'setUserId is not implemented for Lavaca';
    },
    trackEvent: function(category, action, label, value) {
      action = action || '';
      label = label || '';
      value = value || 0;
      if (Device.isCordova()) {
        if (this.ready) {
          analytics.trackEvent(category, action, label, value);
        } else {
          this.queue.push({
            action: 'trackEvent',
            params: [category, action, label, value]
          });
        }
      } else if (this.isWeb) {
        ga('send', {
          'hitType': 'event',
          'eventCategory': category,
          'eventAction': action,
          'eventLabel': label,
          'eventValue': value
        });
      }
    },
    processQueue: function() {
      if (this.queue) {
        var emptyFunction = function() {};
        for (var i = 0; i < this.queue.length; ++i) {
          cordova.exec(emptyFunction, emptyFunction,
            'UniversalAnalytics', this.queue[i].action, this.queue[i].params);
        }
      }
    }
  });

  return new AnalyticsService();
});
<commit_msg>Added not implemented message for lavaca<commit_after>define(function(require) {

  var Disposable = require('lavaca/util/Disposable');
  var Config = require('lavaca/util/Config');
  var Device = require('lavaca/env/Device');
  var ga = require('google-analytics');

  var AnalyticsService = Disposable.extend(function AnalyticsService() {
    Disposable.call(this);
    this.appId = Config.get('google_analytics_id');
    this.webId = Config.get('google_analytics_web_id');
    this.isWeb = this.webId.length;

    if (!Device.isCordova() && this.isWeb) {
      ga('create', this.webId);
    }

    document.addEventListener('deviceready', this.init.bind(this), false);
  }, {
    ready: false,
    queue: [],
    isWeb: false,
    //isApp: false, //TODO need to research when Device.isCordova() is valid in Lavaca load flow
    init: function() {
      if (Device.isCordova() && analytics) {
        this.ready = true;
        analytics.startTrackerWithId(this.appId);
        this.processQueue();
        this.isWeb = false;
      }
    },
    trackView: function(screen) {
      if (Device.isCordova()) {
        if (this.ready) {
          analytics.trackView(screen);
        } else {
          this.queue.push({
            action: 'trackView',
            params: [screen]
          });
        }
      } else if (this.isWeb) {
        ga('send', 'pageview', {
          'title': screen
        });
      }
    },
    setUserId: function() {
      throw 'setUserId is not implemented for Lavaca';
    },
    debugMode: function() {
      throw 'debugMode is not implemented for Lavaca';
    },
    trackEvent: function(category, action, label, value) {
      action = action || '';
      label = label || '';
      value = value || 0;
      if (Device.isCordova()) {
        if (this.ready) {
          analytics.trackEvent(category, action, label, value);
        } else {
          this.queue.push({
            action: 'trackEvent',
            params: [category, action, label, value]
          });
        }
      } else if (this.isWeb) {
        ga('send', {
          'hitType': 'event',
          'eventCategory': category,
          'eventAction': action,
          'eventLabel': label,
          'eventValue': value
        });
      }
    },
    processQueue: function() {
      if (this.queue) {
        var emptyFunction = function() {};
        for (var i = 0; i < this.queue.length; ++i) {
          cordova.exec(emptyFunction, emptyFunction,
            'UniversalAnalytics', this.queue[i].action, this.queue[i].params);
        }
      }
    }
  });

  return new AnalyticsService();
});
<|endoftext|>


<commit_before>var path = require('path')
var FaviconsPlugin = require('favicons-webpack-plugin')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src')
    }
  },
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [resolve('src'), resolve('test')],
        options: {
          formatter: require('eslint-friendly-formatter')
        }
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  plugins: [
      logo: './static/logo.svg',
      prefix: 'icons-[hash]/',
      emitStats: false,
      persistentCache: true,
      inject: true,
      background: '#fff',
      title: 'Abell Design',
      icons: {
        android: true,
        appleIcon: true,
        appleStartup: true,
        coast: false,
        favicons: true,
        firefox: true,
        opengraph: false,
        twitter: false,
        yandex: false,
        windows: false
      }

  ]
}
<commit_msg>fix typo<commit_after>var path = require('path')
var FaviconsPlugin = require('favicons-webpack-plugin')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src')
    }
  },
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [resolve('src'), resolve('test')],
        options: {
          formatter: require('eslint-friendly-formatter')
        }
      },
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
    ]
  },
  plugins: [
    new FaviconsPlugin: ({
      logo: './static/logo.svg',
      prefix: 'icons-[hash]/',
      emitStats: false,
      persistentCache: true,
      inject: true,
      background: '#fff',
      title: 'Abell Design',
      icons: {
        android: true,
        appleIcon: true,
        appleStartup: true,
        coast: false,
        favicons: true,
        firefox: true,
        opengraph: false,
        twitter: false,
        yandex: false,
        windows: false
      }
    })
  ]
}
<|endoftext|>