<commit_before>define(['underscore','jquery','events','codemirror','alto','mybackbone','cmmode', 'dialog'],
    function (_,$,events,CodeMirror,alto,mybackbone, dialog) {
    "use strict";

    var View = mybackbone.View.extend({

        initialize: function () {
            var self = this;
            this.cmConfig = {
                value: "",
                lineWrapping: true,
                mode: 'ocrui',
                changedSince0Sequence: [],
                changedSinceSaveSequence: [],
                languageSequence: [],
                tagSequence: [],
                highlight: {},
                readOnly: true
            };
            this.cMirror = new CodeMirror(this.$el.get(0), this.cmConfig);

            // suppress default codemirror bindings
            CodeMirror.commands.goPageUp = function () { };
            CodeMirror.commands.goPageDown = function () { };

            this.cMirror.on('cursorActivity',function () {
                events.delayOrIgnore('setupHighlightChange',undefined,100);
            });
            this.cMirror.on('change',function (instance) {
                if (self.suppressChanged) return ;
                self.changed(instance);
            });

            self.cMirror.setOption('highlight',{17: true});

        },
        el: '#editor',
        myEvents: {
            'virtualKeyboard':'virtualKeyboard',
            'cursorToCoordinate': 'cursorToCoordinate',
            'refocus':'refocus',
            'changePage':'changePage',
            'changeMode':'changeMode',
            'requestLanguageChange':'requestLanguageChange',
            'setupHighlightChange':'setupHighlightChange',
            'pageDirtyStateChanged':'pageDirtyStateChanged',
            'showLanguage':'showLanguage',
            'showTag': 'showTag',
            'showOriginalChanges':'showOriginalChanges',
            'showSavedChanges':'showSavedChanges',
            'highlightEditorWord':'highlightEditorWord',
            'toggleLineBreak':'toggleLineBreak',
            'altoRefreshed':'altoRefreshed',
            'tagWord': 'tagWord',
            'tagTheWord': 'tagTheWord'
        },
        events: {
            'mouseover .cm-tag': 'mouseoverTag',
            'mouseout .cm-tag': 'mouseoutTag'
        },
        myModes: ['page'],
        altoRefreshed:function(alto) {

            // happens after save
            if (alto.get('pageNumber') == this.attributes.pageNumber) {

                this.setAlto(alto);

            }

        },
        setCMOption:function(opt,val) {
            this.cMirror.setOption(opt,val);
            this.refreshCM();
        },
        refreshCM:function() {

            // No idea what is the proper way, but these three lines together
            // seem to make it work always
            this.cMirror.doc.frontier = this.cMirror.doc.first;
            this.cMirror.setOption('mode',this.cmConfig.mode);
            this.cMirror.replaceSelection(this.cMirror.getSelection());

        },
        mouseoverTag:function(event){
            console.log(event.currentTarget.innerHTML)

            //For some reason for each doesn't work here
            //Loop through the words on a page and show a tooltip when a tagged word is hovered over
            var tagIndex = 0;
            for(var i = 0; i < this.alto.editorWords.length; i++){
                if(this.alto.editorWords[i].content == $.trim(event.currentTarget.innerHTML)){
                    tagIndex = i;
                    break;
                }
            }

            var offset = $(event.currentTarget).offset();

            $("#tagtcontainer").css({'top':offset.top-23,'left':offset.left+25});
            $("#tagt").html("
Tag: "+this.alto.getTagSequence()[tagIndex]+"
");
            $("#tagt").fadeIn(200);

        },
        mouseoutTag:function(event){
            $("#tagt").fadeOut(100);
        },
        toggleLineBreak:function(newState) {

            this.lineBreaks = newState;
            this.setCMOption('lineWrapping', newState ? false : true);
            this.setValueFromAlto();

        },
        highlightEditorWord:function(newState) {
            this.setCMOption('showHighlight',newState);
        },
        showSavedChanges:function(newState) {
            this.setCMOption('showUnsavedChanges',newState);
        },
        showOriginalChanges:function(newState) {
            this.setCMOption('showOriginalChanges',newState);
        },
        showLanguage:function(newState) {
            this.setCMOption('showLanguage',newState);
        },
        showTag:function(newState) {
            this.setCMOption('showTag',newState);
        },
        virtualKeyboard: function(data) {
            this.cMirror.replaceSelection(data);
            this.cMirror.focus();
            var cursor = this.cMirror.getCursor();
            this.cMirror.setCursor(cursor);
        },
        requestLanguageChange: function(selected) {
            var wordIndexes = this.getCurrentWordIndexes();
            for (var wordIndexIndex in wordIndexes) {
                var i = wordIndexes[wordIndexIndex];
                this.alto.setNthWordLanguage(i,selected);
            }
            this.alto.changedSinceSave = true;
            this.cMirror.focus();
        },
        tagWord: function(ev){
            var wordIndexes = this.getCurrentWordIndexes();
            var i = 0;
            for (var wordIndexIndex in wordIndexes) {
                i = wordIndexes[wordIndexIndex];
            }
            events.trigger('showTagDialog', i);
        },
        tagTheWord: function(tagArray){
            console.log(tagArray.index + " " + tagArray.tag);
            this.alto.setNthWordTag(tagArray.index, tagArray.tag);
            this.alto.changedSinceSave = true;
            events.trigger("saveDocument");
            this.cMirror.focus();
        },
        refocus: function(ev) {
            this.cMirror.focus();
        },
        cursorToCoordinate: function(coords) {
            var content = this.cMirror.getValue();
            var line = 0;
            var ch = 0;
            var anchor,head;
            var betweenWords = false;
            if (!this.alto) { return; }
            var word = this.alto.getWordAt(coords.x,coords.y);
            if (word === undefined) {return;}
            var wordIndex = word.index;
            var wordLength = word.content.length;
            for (var i in content) {
                var c = content[i];
                if (c == '\n') {
                    line ++;
                    ch = -1;
                }
                if (c.match(/\s/)) {
                    betweenWords = true;
                } else {
                    if (betweenWords) wordIndex --;
                    if (wordIndex === 0) {
                        if (anchor === undefined) {
                            anchor = {
                                line: line,
                                ch: ch
                            }
                        }
                        head = {
                            line: line,
                            ch: ch + 1
                        }
                        wordLength --;
                        if (wordLength == 0) {
                            break;
                        }
                    }
                    betweenWords = false;
                }
                ch ++;
            }
            this.cMirror.setSelection(anchor,head);
            this.cMirror.focus();
        },
        configureCMMode: function () {
            this.cmConfig.changedSinceSaveSequence =
                this.alto.getChangedSinceSaveSequence();
            this.cmConfig.changedSince0Sequence
                = this.alto.getChangedSince0Sequence();
            this.cmConfig.languageSequence = this.alto.getLanguageSequence();
            this.cmConfig.tagSequence = this.alto.getTagSequence();
        },
        changed: function (instance) {
            var content = instance.getValue();

            if (!this.alto) return;

            this.alto.updateStringsContent(content.split(/\s+/));
            this.configureCMMode();
            this.setupHighlightChange();
        },
        getCurrentWordIndexes: function () {
            var wordIndexes = {};
            var wordIndex = -1; // in between words before first word...
            var content = this.cMirror.getValue();
            var start = this.cMirror.getCursor('start');
            var end = this.cMirror.getCursor('end');
            var s_line = start.line;
            var s_ch = start.ch;
            var e_line = end.line;
            var e_ch = end.ch;
            var betweenWords = true;
            var stillBetweenWords = false;

            for (var i in content) {

                var c = content[i];

                if (c.match(/\s/)) {

                    if (betweenWords) stillBetweenWords = true;
                    betweenWords = true;

                } else {

                    if (betweenWords) wordIndex ++;
                    betweenWords = false;
                    stillBetweenWords = false;

                }

                if (s_line <= 0) {
                    s_ch --;
                    if ((s_ch < 0) && (!stillBetweenWords)) {
                        wordIndexes[wordIndex] = true;
                    }
                }

                if (e_line <=0) {
                    e_ch --;
                    if (e_ch < 0) break;
                }

                if (c == '\n') {
                    s_line --;
                    e_line --;
                }
            }

            this.words = wordIndexes;
            var wordIndexArray = _.map(wordIndexes,function (v,k) {
                return parseInt(k,10);
            });
            return wordIndexArray;
        },
        setupHighlightChange: function () {

            var wordIndexes = this.getCurrentWordIndexes();
            var self = this;
            console.log(wordIndexes);
            var words = _.map(wordIndexes,function (v,k) {

                return self.alto.getNthWord(v);

            });

            self.cMirror.setOption('highlight',this.words);
            this.suppressChanged = true;
            this.cMirror.doc.frontier = this.cMirror.doc.first;
            this.cMirror.replaceSelection(this.cMirror.getSelection());
            this.suppressChanged = false;

            events.trigger('changeCoordinates',words);

        },
        changePage: function(attributes) {
            var self = this;
            this.attributes = attributes;
            alto.get(attributes).then(
                function(myAlto) {
                    /* if (this.attributes != attributes) return;*/
                    self.setAlto(myAlto);
                },
                function(msg) {
                    events.trigger('editorRenderError',{
                        error: 'editorRenderError',
                        message: msg
                    });
                }
            );
        },
        pageDirtyStateChanged: function() {
            if(this.alto.isDirty()) {
                this.$el.addClass('dirty');
            } else {
                this.$el.removeClass('dirty');
            }
        },
        setValueFromAlto: function(alto) {
            if (this.alto === undefined) {
                this.cMirror.setValue("");
            } else {
                var s = this.alto.getString(this.lineBreaks);
                this.cMirror.setValue(s);
            }
        },
        setAlto: function(alto) {
            this.alto = alto;
            this.setValueFromAlto();
            this.cMirror.clearHistory();
            var word = this.alto.getNthWord(0);
            this.cMirror.focus();
            events.trigger('editorRendered',this.attributes);
        },
        render: function() {
            return;     // Nothing to do, CodeMirror renders itself
        }
    });

    return {
        view: new View()
    };

});
<commit_msg>read only mode<commit_after>define(['underscore','jquery','events','codemirror','alto','mybackbone','cmmode', 'dialog'],
    function (_,$,events,CodeMirror,alto,mybackbone, dialog) {
    "use strict";

    var View = mybackbone.View.extend({

        initialize: function () {
            var options = {
                type:'GET',
                url: "/api/id/"+uid+"/ping",
                statusCode: {
                    401: function() {events.trigger("saveFailed401", 'pinging the backend')},
                    403: function() {events.trigger("saveFailed", 'Forbidden')},
                }
            }
            var readonly = false;
            $.ajax(options)
                .done(function(data){
                    console.log(data)
                    if(data.code == 13){
                        console.log("ReadOnly");
                        $('#save').hide();
                        readonly = true;
                    }
                    view.render("ping");
                });
            var self = this;
            this.cmConfig = {
                value: "",
                lineWrapping: true,
                mode: 'ocrui',
                changedSince0Sequence: [],
                changedSinceSaveSequence: [],
                languageSequence: [],
                tagSequence: [],
                highlight: {},
                readOnly: readonly
            };
            this.cMirror = new CodeMirror(this.$el.get(0), this.cmConfig);

            // suppress default codemirror bindings
            CodeMirror.commands.goPageUp = function () { };
            CodeMirror.commands.goPageDown = function () { };

            this.cMirror.on('cursorActivity',function () {
                events.delayOrIgnore('setupHighlightChange',undefined,100);
            });
            this.cMirror.on('change',function (instance) {
                if (self.suppressChanged) return ;
                self.changed(instance);
            });

            self.cMirror.setOption('highlight',{17: true});

        },
        el: '#editor',
        myEvents: {
            'virtualKeyboard':'virtualKeyboard',
            'cursorToCoordinate': 'cursorToCoordinate',
            'refocus':'refocus',
            'changePage':'changePage',
            'changeMode':'changeMode',
            'requestLanguageChange':'requestLanguageChange',
            'setupHighlightChange':'setupHighlightChange',
            'pageDirtyStateChanged':'pageDirtyStateChanged',
            'showLanguage':'showLanguage',
            'showTag': 'showTag',
            'showOriginalChanges':'showOriginalChanges',
            'showSavedChanges':'showSavedChanges',
            'highlightEditorWord':'highlightEditorWord',
            'toggleLineBreak':'toggleLineBreak',
            'altoRefreshed':'altoRefreshed',
            'tagWord': 'tagWord',
            'tagTheWord': 'tagTheWord'
        },
        events: {
            'mouseover .cm-tag': 'mouseoverTag',
            'mouseout .cm-tag': 'mouseoutTag'
        },
        myModes: ['page'],
        altoRefreshed:function(alto) {

            // happens after save
            if (alto.get('pageNumber') == this.attributes.pageNumber) {

                this.setAlto(alto);

            }

        },
        setCMOption:function(opt,val) {
            this.cMirror.setOption(opt,val);
            this.refreshCM();
        },
        refreshCM:function() {

            // No idea what is the proper way, but these three lines together
            // seem to make it work always
            this.cMirror.doc.frontier = this.cMirror.doc.first;
            this.cMirror.setOption('mode',this.cmConfig.mode);
            this.cMirror.replaceSelection(this.cMirror.getSelection());

        },
        mouseoverTag:function(event){
            console.log(event.currentTarget.innerHTML)

            //For some reason for each doesn't work here
            //Loop through the words on a page and show a tooltip when a tagged word is hovered over
            var tagIndex = 0;
            for(var i = 0; i < this.alto.editorWords.length; i++){
                if(this.alto.editorWords[i].content == $.trim(event.currentTarget.innerHTML)){
                    tagIndex = i;
                    break;
                }
            }

            var offset = $(event.currentTarget).offset();

            $("#tagtcontainer").css({'top':offset.top-23,'left':offset.left+25});
            $("#tagt").html("
Tag: "+this.alto.getTagSequence()[tagIndex]+"
");
            $("#tagt").fadeIn(200);

        },
        mouseoutTag:function(event){
            $("#tagt").fadeOut(100);
        },
        toggleLineBreak:function(newState) {

            this.lineBreaks = newState;
            this.setCMOption('lineWrapping', newState ? false : true);
            this.setValueFromAlto();

        },
        highlightEditorWord:function(newState) {
            this.setCMOption('showHighlight',newState);
        },
        showSavedChanges:function(newState) {
            this.setCMOption('showUnsavedChanges',newState);
        },
        showOriginalChanges:function(newState) {
            this.setCMOption('showOriginalChanges',newState);
        },
        showLanguage:function(newState) {
            this.setCMOption('showLanguage',newState);
        },
        showTag:function(newState) {
            this.setCMOption('showTag',newState);
        },
        virtualKeyboard: function(data) {
            this.cMirror.replaceSelection(data);
            this.cMirror.focus();
            var cursor = this.cMirror.getCursor();
            this.cMirror.setCursor(cursor);
        },
        requestLanguageChange: function(selected) {
            var wordIndexes = this.getCurrentWordIndexes();
            for (var wordIndexIndex in wordIndexes) {
                var i = wordIndexes[wordIndexIndex];
                this.alto.setNthWordLanguage(i,selected);
            }
            this.alto.changedSinceSave = true;
            this.cMirror.focus();
        },
        tagWord: function(ev){
            var wordIndexes = this.getCurrentWordIndexes();
            var i = 0;
            for (var wordIndexIndex in wordIndexes) {
                i = wordIndexes[wordIndexIndex];
            }
            events.trigger('showTagDialog', i);
        },
        tagTheWord: function(tagArray){
            console.log(tagArray.index + " " + tagArray.tag);
            this.alto.setNthWordTag(tagArray.index, tagArray.tag);
            this.alto.changedSinceSave = true;
            events.trigger("saveDocument");
            this.cMirror.focus();
        },
        refocus: function(ev) {
            this.cMirror.focus();
        },
        cursorToCoordinate: function(coords) {
            var content = this.cMirror.getValue();
            var line = 0;
            var ch = 0;
            var anchor,head;
            var betweenWords = false;
            if (!this.alto) { return; }
            var word = this.alto.getWordAt(coords.x,coords.y);
            if (word === undefined) {return;}
            var wordIndex = word.index;
            var wordLength = word.content.length;
            for (var i in content) {
                var c = content[i];
                if (c == '\n') {
                    line ++;
                    ch = -1;
                }
                if (c.match(/\s/)) {
                    betweenWords = true;
                } else {
                    if (betweenWords) wordIndex --;
                    if (wordIndex === 0) {
                        if (anchor === undefined) {
                            anchor = {
                                line: line,
                                ch: ch
                            }
                        }
                        head = {
                            line: line,
                            ch: ch + 1
                        }
                        wordLength --;
                        if (wordLength == 0) {
                            break;
                        }
                    }
                    betweenWords = false;
                }
                ch ++;
            }
            this.cMirror.setSelection(anchor,head);
            this.cMirror.focus();
        },
        configureCMMode: function () {
            this.cmConfig.changedSinceSaveSequence =
                this.alto.getChangedSinceSaveSequence();
            this.cmConfig.changedSince0Sequence
                = this.alto.getChangedSince0Sequence();
            this.cmConfig.languageSequence = this.alto.getLanguageSequence();
            this.cmConfig.tagSequence = this.alto.getTagSequence();
        },
        changed: function (instance) {
            var content = instance.getValue();

            if (!this.alto) return;

            this.alto.updateStringsContent(content.split(/\s+/));
            this.configureCMMode();
            this.setupHighlightChange();
        },
        getCurrentWordIndexes: function () {
            var wordIndexes = {};
            var wordIndex = -1; // in between words before first word...
            var content = this.cMirror.getValue();
            var start = this.cMirror.getCursor('start');
            var end = this.cMirror.getCursor('end');
            var s_line = start.line;
            var s_ch = start.ch;
            var e_line = end.line;
            var e_ch = end.ch;
            var betweenWords = true;
            var stillBetweenWords = false;

            for (var i in content) {

                var c = content[i];

                if (c.match(/\s/)) {

                    if (betweenWords) stillBetweenWords = true;
                    betweenWords = true;

                } else {

                    if (betweenWords) wordIndex ++;
                    betweenWords = false;
                    stillBetweenWords = false;

                }

                if (s_line <= 0) {
                    s_ch --;
                    if ((s_ch < 0) && (!stillBetweenWords)) {
                        wordIndexes[wordIndex] = true;
                    }
                }

                if (e_line <=0) {
                    e_ch --;
                    if (e_ch < 0) break;
                }

                if (c == '\n') {
                    s_line --;
                    e_line --;
                }
            }

            this.words = wordIndexes;
            var wordIndexArray = _.map(wordIndexes,function (v,k) {
                return parseInt(k,10);
            });
            return wordIndexArray;
        },
        setupHighlightChange: function () {

            var wordIndexes = this.getCurrentWordIndexes();
            var self = this;
            console.log(wordIndexes);
            var words = _.map(wordIndexes,function (v,k) {

                return self.alto.getNthWord(v);

            });

            self.cMirror.setOption('highlight',this.words);
            this.suppressChanged = true;
            this.cMirror.doc.frontier = this.cMirror.doc.first;
            this.cMirror.replaceSelection(this.cMirror.getSelection());
            this.suppressChanged = false;

            events.trigger('changeCoordinates',words);

        },
        changePage: function(attributes) {
            var self = this;
            this.attributes = attributes;
            alto.get(attributes).then(
                function(myAlto) {
                    /* if (this.attributes != attributes) return;*/
                    self.setAlto(myAlto);
                },
                function(msg) {
                    events.trigger('editorRenderError',{
                        error: 'editorRenderError',
                        message: msg
                    });
                }
            );
        },
        pageDirtyStateChanged: function() {
            if(this.alto.isDirty()) {
                this.$el.addClass('dirty');
            } else {
                this.$el.removeClass('dirty');
            }
        },
        setValueFromAlto: function(alto) {
            if (this.alto === undefined) {
                this.cMirror.setValue("");
            } else {
                var s = this.alto.getString(this.lineBreaks);
                this.cMirror.setValue(s);
            }
        },
        setAlto: function(alto) {
            this.alto = alto;
            this.setValueFromAlto();
            this.cMirror.clearHistory();
            var word = this.alto.getNthWord(0);
            this.cMirror.focus();
            events.trigger('editorRendered',this.attributes);
        },
        render: function() {
            return;     // Nothing to do, CodeMirror renders itself
        }
    });

    return {
        view: new View()
    };

});
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import "./backend";
import "./svg";
import {Presentation} from "./model/Presentation";
import {Selection} from "./model/Selection";
import {Preferences} from "./model/Preferences";
import {Storage} from "./Storage";
import {Viewport} from "./player/Viewport";
import {Player} from "./player/Player";
import {Controller} from "./Controller";
import {Preview} from "./view/Preview";
import {Properties} from "./view/Properties";
import {Toolbar} from "./view/Toolbar";
import {Timeline} from "./view/Timeline";

import nunjucks from "nunjucks";
import * as i18n from "./i18n";

window.addEventListener("load", () => {
    nunjucks.configure({watch: false});

    Notification.requestPermission();

    const presentation = new Presentation();
    const selection    = new Selection(presentation);
    const viewport     = new Viewport(presentation, true);
    const player       = new Player(viewport, presentation, true);

    const locale       = i18n.init();
    const preferences  = new Preferences();
    const controller   = new Controller(preferences, presentation, selection, viewport, player, locale);
    const preview      = new Preview(document.getElementById("sozi-editor-view-preview"), presentation, selection, viewport, controller);
    const properties   = new Properties(document.getElementById("sozi-editor-view-properties"), selection, controller);
    const toolbar      = new Toolbar(document.getElementById("sozi-editor-view-toolbar"), properties, presentation, viewport, controller);
    const timeline     = new Timeline(document.getElementById("sozi-editor-view-timeline"), presentation, selection, controller);
    const storage      = new Storage(controller, presentation, selection);

    const body         = document.querySelector("body");
    const left         = document.querySelector(".left");
    const right        = document.querySelector(".right");
    const top          = document.querySelector(".top");
    const bottom       = document.querySelector(".bottom");
    const hsplitter    = document.querySelector(".hsplitter");
    const vsplitter    = document.querySelector(".vsplitter");

    document.getElementById("message").addEventListener("click", evt => {
        controller.hideNotification();
        evt.stopPropagation();
    });

    let hsplitterStartY, vsplitterStartX;

    const hsplitterHeight = hsplitter.getBoundingClientRect().height;
    const vsplitterWidth  = vsplitter.getBoundingClientRect().width;

    function hsplitterOnMouseMove(evt) {
        const topHeightPercent = 100 * (hsplitterStartY + evt.clientY) / window.innerHeight;
        top.style.height    = topHeightPercent + "%";
        hsplitter.style.top = topHeightPercent + "%";
        bottom.style.height = `calc(${100 - topHeightPercent}% - ${hsplitterHeight}px)`;
        window.dispatchEvent(new UIEvent("resize"));
        return false;
    }

    function hsplitterOnMouseUp() {
        body.removeEventListener("mousemove", hsplitterOnMouseMove);
        body.removeEventListener("mouseup",   hsplitterOnMouseUp);
    }

    function vsplitterOnMouseMove(evt) {
        const leftWidthPercent = 100 * (vsplitterStartX + evt.clientX) / window.innerWidth;
        left.style.width     = leftWidthPercent + "%";
        vsplitter.style.left = leftWidthPercent + "%";
        right.style.width    = `calc(${100 - leftWidthPercent}% - ${vsplitterWidth}px)`;
        window.dispatchEvent(new UIEvent("resize"));
        return false;
    }

    function vsplitterOnMouseUp() {
        body.removeEventListener("mousemove", vsplitterOnMouseMove);
        body.removeEventListener("mouseup",   vsplitterOnMouseUp);
    }

    hsplitter.addEventListener("mousedown", evt => {
        hsplitterStartY = hsplitter.getBoundingClientRect().top - evt.clientY;
        body.addEventListener("mousemove", hsplitterOnMouseMove);
        body.addEventListener("mouseup",   hsplitterOnMouseUp);
    });

    vsplitter.addEventListener("mousedown", evt => {
        vsplitterStartX = vsplitter.getBoundingClientRect().left - evt.clientX;
        body.addEventListener("mousemove", vsplitterOnMouseMove);
        body.addEventListener("mouseup",   vsplitterOnMouseUp);
    });

    window.addEventListener("keydown", evt => {
        let key = "";
        if (evt.ctrlKey) {
            key += "Ctrl+";
        }
        if (evt.altKey) {
            key += "Alt+";
        }
        if (evt.shiftKey) {
            key += "Shift+";
        }
        key += evt.key.toUpperCase();

        let actionFound = null;

        for (let action in preferences.keys) {
            if (preferences.keys[action] === key) {
                actionFound = action;
                break;
            }
        }

        switch (actionFound) {
            case "autoselectOutlineElement":
                controller.autoselectOutlineElement();
                break;
            case "resetLayer":
                controller.resetLayer();
                break;
            case "addFrame":
                controller.addFrame();
                break;
            case "save":
                controller.save();
                break;
            case "redo":
                controller.redo();
                break;
            case "undo":
                controller.undo();
                break;
            case "focusTitleField":
                document.getElementById('field-title').select();
                break;
            case "reload":
                controller.reload();
                break;
            case "toggleFullscreen":
                document.getElementById('btn-fullscreen').click();
                break;
            case "toggleDevTools":
                storage.backend.toggleDevTools();
                break;
        }

        // Keyboard acctions that may collide with text inputs.
        if (!actionFound && !/input|select|textarea|section/i.test(document.activeElement.tagName)) {
            actionFound = true;
            switch (evt.key) {
                case "End":
                    controller.selectFrame(-1);
                    break;
                case "Home":
                    controller.selectFrame(0);
                    break;
                case "ArrowLeft":
                    controller.selectRelativeFrame(-1);
                    break;
                case "ArrowRight":
                    controller.selectRelativeFrame(1);
                    break;
                case "Delete":
                    controller.deleteFrames();
                    break;
                case "a":
                    if (evt.ctrlKey) {
                        controller.selectAllFrames();
                    }
                    else {
                        actionFound = false;
                    }
                    break;
                default:
                    actionFound = false;
            }
        }

        if (actionFound) {
            evt.preventDefault();
        }
    }, false);
}, false);
<commit_msg>Fixes #472 - Validate active input field when a keyboard action is executed<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import "./backend";
import "./svg";
import {Presentation} from "./model/Presentation";
import {Selection} from "./model/Selection";
import {Preferences} from "./model/Preferences";
import {Storage} from "./Storage";
import {Viewport} from "./player/Viewport";
import {Player} from "./player/Player";
import {Controller} from "./Controller";
import {Preview} from "./view/Preview";
import {Properties} from "./view/Properties";
import {Toolbar} from "./view/Toolbar";
import {Timeline} from "./view/Timeline";

import nunjucks from "nunjucks";
import * as i18n from "./i18n";

window.addEventListener("load", () => {
    nunjucks.configure({watch: false});

    Notification.requestPermission();

    const presentation = new Presentation();
    const selection    = new Selection(presentation);
    const viewport     = new Viewport(presentation, true);
    const player       = new Player(viewport, presentation, true);

    const locale       = i18n.init();
    const preferences  = new Preferences();
    const controller   = new Controller(preferences, presentation, selection, viewport, player, locale);
    const preview      = new Preview(document.getElementById("sozi-editor-view-preview"), presentation, selection, viewport, controller);
    const properties   = new Properties(document.getElementById("sozi-editor-view-properties"), selection, controller);
    const toolbar      = new Toolbar(document.getElementById("sozi-editor-view-toolbar"), properties, presentation, viewport, controller);
    const timeline     = new Timeline(document.getElementById("sozi-editor-view-timeline"), presentation, selection, controller);
    const storage      = new Storage(controller, presentation, selection);

    const body         = document.querySelector("body");
    const left         = document.querySelector(".left");
    const right        = document.querySelector(".right");
    const top          = document.querySelector(".top");
    const bottom       = document.querySelector(".bottom");
    const hsplitter    = document.querySelector(".hsplitter");
    const vsplitter    = document.querySelector(".vsplitter");

    document.getElementById("message").addEventListener("click", evt => {
        controller.hideNotification();
        evt.stopPropagation();
    });

    let hsplitterStartY, vsplitterStartX;

    const hsplitterHeight = hsplitter.getBoundingClientRect().height;
    const vsplitterWidth  = vsplitter.getBoundingClientRect().width;

    function hsplitterOnMouseMove(evt) {
        const topHeightPercent = 100 * (hsplitterStartY + evt.clientY) / window.innerHeight;
        top.style.height    = topHeightPercent + "%";
        hsplitter.style.top = topHeightPercent + "%";
        bottom.style.height = `calc(${100 - topHeightPercent}% - ${hsplitterHeight}px)`;
        window.dispatchEvent(new UIEvent("resize"));
        return false;
    }

    function hsplitterOnMouseUp() {
        body.removeEventListener("mousemove", hsplitterOnMouseMove);
        body.removeEventListener("mouseup",   hsplitterOnMouseUp);
    }

    function vsplitterOnMouseMove(evt) {
        const leftWidthPercent = 100 * (vsplitterStartX + evt.clientX) / window.innerWidth;
        left.style.width     = leftWidthPercent + "%";
        vsplitter.style.left = leftWidthPercent + "%";
        right.style.width    = `calc(${100 - leftWidthPercent}% - ${vsplitterWidth}px)`;
        window.dispatchEvent(new UIEvent("resize"));
        return false;
    }

    function vsplitterOnMouseUp() {
        body.removeEventListener("mousemove", vsplitterOnMouseMove);
        body.removeEventListener("mouseup",   vsplitterOnMouseUp);
    }

    hsplitter.addEventListener("mousedown", evt => {
        hsplitterStartY = hsplitter.getBoundingClientRect().top - evt.clientY;
        body.addEventListener("mousemove", hsplitterOnMouseMove);
        body.addEventListener("mouseup",   hsplitterOnMouseUp);
    });

    vsplitter.addEventListener("mousedown", evt => {
        vsplitterStartX = vsplitter.getBoundingClientRect().left - evt.clientX;
        body.addEventListener("mousemove", vsplitterOnMouseMove);
        body.addEventListener("mouseup",   vsplitterOnMouseUp);
    });

    window.addEventListener("keydown", evt => {
        let key = "";
        if (evt.ctrlKey) {
            key += "Ctrl+";
        }
        if (evt.altKey) {
            key += "Alt+";
        }
        if (evt.shiftKey) {
            key += "Shift+";
        }
        key += evt.key.toUpperCase();

        let actionFound = null;

        for (let action in preferences.keys) {
            if (preferences.keys[action] === key) {
                actionFound = action;
                break;
            }
        }

        // If an action was found, validate the active input field
        // before executing the action.
        const inputFocused = document.activeElement && /input|select|textarea|section/i.test(document.activeElement.tagName);

        if (actionFound && inputFocused) {
            document.activeElement.blur();
        }

        switch (actionFound) {
            case "autoselectOutlineElement":
                controller.autoselectOutlineElement();
                break;
            case "resetLayer":
                controller.resetLayer();
                break;
            case "addFrame":
                controller.addFrame();
                break;
            case "save":
                controller.save();
                break;
            case "redo":
                controller.redo();
                break;
            case "undo":
                controller.undo();
                break;
            case "focusTitleField":
                document.getElementById('field-title').select();
                break;
            case "reload":
                controller.reload();
                break;
            case "toggleFullscreen":
                document.getElementById('btn-fullscreen').click();
                break;
            case "toggleDevTools":
                storage.backend.toggleDevTools();
                break;
        }

        // Keyboard actions that may collide with input fields
        // are executed only if no input element has the focus.
        if (!actionFound && !inputFocused) {
            actionFound = true;
            switch (evt.key) {
                case "End":
                    controller.selectFrame(-1);
                    break;
                case "Home":
                    controller.selectFrame(0);
                    break;
                case "ArrowLeft":
                    controller.selectRelativeFrame(-1);
                    break;
                case "ArrowRight":
                    controller.selectRelativeFrame(1);
                    break;
                case "Delete":
                    controller.deleteFrames();
                    break;
                case "a":
                    if (evt.ctrlKey) {
                        controller.selectAllFrames();
                    }
                    else {
                        actionFound = false;
                    }
                    break;
                default:
                    actionFound = false;
            }
        }

        if (actionFound) {
            evt.preventDefault();
        }
    }, false);
}, false);
<|endoftext|>


<commit_before>/* Engine.js
 * This file provides the game loop functionality (update entities and render),
 * draws the initial game board on the screen, and then calls the update and
 * render methods on your player and enemy objects (defined in your app.js).
 *
 * A game engine works by drawing the entire game screen over and over, kind of
 * like a flipbook you may have created as a kid. When your player moves across
 * the screen, it may look like just that image/character is moving or being
 * drawn but that is not the case. What's really happening is the entire "scene"
 * is being drawn over and over, presenting the illusion of animation.
 *
 * This engine is available globally via the Engine variable and it also makes
 * the canvas' context (ctx) object globally available to make writing app.js
 * a little simpler to work with.
 */

var Engine = (function(global) {
    /* Predefine the variables we'll be using within this scope,
     * create the canvas element, grab the 2D context for that canvas
     * set the canvas elements height/width and add it to the DOM.
     */
    var doc = global.document,
        win = global.window,
        canvas = doc.createElement('canvas'),
        ctx = canvas.getContext('2d'),
        lastTime;

    canvas.width = 505;
    canvas.height = 606;
    doc.body.appendChild(canvas);

    /* This function serves as the kickoff point for the game loop itself
     * and handles properly calling the update and render methods.
     */
    function main() {
        /* Get our time delta information which is required if your game
         * requires smooth animation. Because everyone's computer processes
         * instructions at different speeds we need a constant value that
         * would be the same for everyone (regardless of how fast their
         * computer is) - hurray time!
         */
        var now = Date.now(),
            dt = (now - lastTime) / 1000.0;

        /* Call our update/render functions, pass along the time delta to
         * our update function since it may be used for smooth animation.
         */
        update(dt);
        render();

        /* Set our lastTime variable which is used to determine the time delta
         * for the next time this function is called.
         */
        lastTime = now;

        /* Use the browser's requestAnimationFrame function to call this
         * function again as soon as the browser is able to draw another frame.
         */
        win.requestAnimationFrame(main);
    };

    /* This function does some initial setup that should only occur once,
     * particularly setting the lastTime variable that is required for the
     * game loop.
     */
    function init() {
        reset();
        lastTime = Date.now();
        main();
    }

    /* This function is called by main (our game loop) and itself calls all
     * of the functions which may need to update entity's data. Based on how
     * you implement your collision detection (when two entities occupy the
     * same space, for instance when your character should die), you may find
     * the need to add an additional function call here. For now, we've left
     * it commented out - you may or may not want to implement this
     * functionality this way (you could just implement collision detection
     * on the entities themselves within your app.js file).
     */
    function update(dt) {
        updateEntities(dt);
        // checkCollisions();
    }

    /* This is called by the update function  and loops through all of the
     * objects within your allEnemies array as defined in app.js and calls
     * their update() methods. It will then call the update function for your
     * player object. These update methods should focus purely on updating
     * the data/properties related to  the object. Do your drawing in your
     * render methods.
     */
    function updateEntities(dt) {
        // allEnemies.forEach(function(enemy) {
        //     enemy.update(dt);
        // });
        // player.update();
    }

    /* This function initially draws the "game level", it will then call
     * the renderEntities function. Remember, this function is called every
     * game tick (or loop of the game engine) because that's how games work -
     * they are flipbooks creating the illusion of animation but in reality
     * they are just drawing the entire screen over and over.
     */
    function render() {
        // /* This array holds the relative URL to the image used
        //  * for that particular row of the game level.
        //  */
        // var rowImages = [
        //         'images/water-block.png',   // Top row is water
        //         'images/stone-block.png',   // Row 1 of 3 of stone
        //         'images/stone-block.png',   // Row 2 of 3 of stone
        //         'images/stone-block.png',   // Row 3 of 3 of stone
        //         'images/grass-block.png',   // Row 1 of 2 of grass
        //         'images/grass-block.png'    // Row 2 of 2 of grass
        //     ],
        //     numRows = 6,
        //     numCols = 5,
        //     row, col;

        //  Loop through the number of rows and columns we've defined above
        //  * and, using the rowImages array, draw the correct image for that
        //  * portion of the "grid"

        // for (row = 0; row < numRows; row++) {
        //     for (col = 0; col < numCols; col++) {
        //         /* The drawImage function of the canvas' context element
        //          * requires 3 parameters: the image to draw, the x coordinate
        //          * to start drawing and the y coordinate to start drawing.
        //          * We're using our Resources helpers to refer to our images
        //          * so that we get the benefits of caching these images, since
        //          * we're using them over and over.
        //          */
        //         ctx.drawImage(Resources.get(rowImages[row]), col * 101, row * 83);
        //     }
        // }

        renderEntities();
    }

    /* This function is called by the render function and is called on each game
     * tick. It's purpose is to then call the render functions you have defined
     * on your enemy and player entities within app.js
     */
    function renderEntities() {
        /* Loop through all of the objects within the allEnemies array and call
         * the render function you have defined.
         */
        allEnemies.forEach(function(enemy) {
            enemy.render();
        });

        player.render();
    }

    /* This function does nothing but it could have been a good place to
     * handle game reset states - maybe a new game menu or a game over screen
     * those sorts of things. It's only called once by the init() method.
     */
    function reset() {
        // noop
    }

    /* Go ahead and load all of the images we know we're going to need to
     * draw our game level. Then set init as the callback method, so that when
     * all of these images are properly loaded our game will start.
     */
    Resources.load([
        // 'images/stone-block.png',
        // 'images/water-block.png',
        // 'images/grass-block.png',
        // 'images/enemy-bug.png',
        // 'images/char-boy.png'
    ]);
    Resources.onReady(init);

    /* Assign the canvas' context object to the global variable (the window
     * object when run in a browser) so that developer's can use it more easily
     * from within their app.js files.
     */
    global.ctx = ctx;
})(this);<commit_msg>feat: added image folder and made edits to engine.js to appropriate to my game's needs<commit_after>/* Engine.js
 * This file provides the game loop functionality (update entities and render),
 * draws the initial game board on the screen, and then calls the update and
 * render methods on your player and enemy objects (defined in your app.js).
 *
 * A game engine works by drawing the entire game screen over and over, kind of
 * like a flipbook you may have created as a kid. When your player moves across
 * the screen, it may look like just that image/character is moving or being
 * drawn but that is not the case. What's really happening is the entire "scene"
 * is being drawn over and over, presenting the illusion of animation.
 *
 * This engine is available globally via the Engine variable and it also makes
 * the canvas' context (ctx) object globally available to make writing app.js
 * a little simpler to work with.
 */

var Engine = (function(global) {
    /* Predefine the variables we'll be using within this scope,
     * create the canvas element, grab the 2D context for that canvas
     * set the canvas elements height/width and add it to the DOM.
     */
    var doc = global.document,
        win = global.window,
        canvas = doc.createElement('canvas'),
        ctx = canvas.getContext('2d'),
        lastTime;

    canvas.width = 805;
    canvas.height = 606;
    canvas.style.border = "1px solid";
    doc.body.appendChild(canvas);

    /* This function serves as the kickoff point for the game loop itself
     * and handles properly calling the update and render methods.
     */
    function main() {
        /* Get our time delta information which is required if your game
         * requires smooth animation. Because everyone's computer processes
         * instructions at different speeds we need a constant value that
         * would be the same for everyone (regardless of how fast their
         * computer is) - hurray time!
         */
        var now = Date.now(),
            dt = (now - lastTime) / 1000.0;

        /* Call our update/render functions, pass along the time delta to
         * our update function since it may be used for smooth animation.
         */
        update(dt);
        render();

        /* Set our lastTime variable which is used to determine the time delta
         * for the next time this function is called.
         */
        lastTime = now;

        /* Use the browser's requestAnimationFrame function to call this
         * function again as soon as the browser is able to draw another frame.
         */
        win.requestAnimationFrame(main);
    };

    /* This function does some initial setup that should only occur once,
     * particularly setting the lastTime variable that is required for the
     * game loop.
     */
    function init() {
        reset();
        lastTime = Date.now();
        main();
    }

    /* This function is called by main (our game loop) and itself calls all
     * of the functions which may need to update entity's data. Based on how
     * you implement your collision detection (when two entities occupy the
     * same space, for instance when your character should die), you may find
     * the need to add an additional function call here. For now, we've left
     * it commented out - you may or may not want to implement this
     * functionality this way (you could just implement collision detection
     * on the entities themselves within your app.js file).
     */
    function update(dt) {
        updateEntities(dt);
        // checkCollisions();
    }

    /* This is called by the update function  and loops through all of the
     * objects within your allEnemies array as defined in app.js and calls
     * their update() methods. It will then call the update function for your
     * player object. These update methods should focus purely on updating
     * the data/properties related to  the object. Do your drawing in your
     * render methods.
     */
    function updateEntities(dt) {
        // allEnemies.forEach(function(enemy) {
        //     enemy.update(dt);
        // });
        // player.update();
    }

    /* This function initially draws the "game level", it will then call
     * the renderEntities function. Remember, this function is called every
     * game tick (or loop of the game engine) because that's how games work -
     * they are flipbooks creating the illusion of animation but in reality
     * they are just drawing the entire screen over and over.
     */
    function render() {
        // /* This array holds the relative URL to the image used
        //  * for that particular row of the game level.
        //  */
        // var rowImages = [
        //         'images/water-block.png',   // Top row is water
        //         'images/stone-block.png',   // Row 1 of 3 of stone
        //         'images/stone-block.png',   // Row 2 of 3 of stone
        //         'images/stone-block.png',   // Row 3 of 3 of stone
        //         'images/grass-block.png',   // Row 1 of 2 of grass
        //         'images/grass-block.png'    // Row 2 of 2 of grass
        //     ],
        //     numRows = 6,
        //     numCols = 5,
        //     row, col;

        //  Loop through the number of rows and columns we've defined above
        //  * and, using the rowImages array, draw the correct image for that
        //  * portion of the "grid"

        // for (row = 0; row < numRows; row++) {
        //     for (col = 0; col < numCols; col++) {
        //         /* The drawImage function of the canvas' context element
        //          * requires 3 parameters: the image to draw, the x coordinate
        //          * to start drawing and the y coordinate to start drawing.
        //          * We're using our Resources helpers to refer to our images
        //          * so that we get the benefits of caching these images, since
        //          * we're using them over and over.
        //          */
        //         ctx.drawImage(Resources.get(rowImages[row]), col * 101, row * 83);
        //     }
        // }

        renderEntities();
    }

    /* This function is called by the render function and is called on each game
     * tick. It's purpose is to then call the render functions you have defined
     * on your enemy and player entities within app.js
     */
    function renderEntities() {
        /* Loop through all of the objects within the allEnemies array and call
         * the render function you have defined.
         */
        allEnemies.forEach(function(enemy) {
            enemy.render();
        });

        player.render();
    }

    /* This function does nothing but it could have been a good place to
     * handle game reset states - maybe a new game menu or a game over screen
     * those sorts of things. It's only called once by the init() method.
     */
    function reset() {
        // noop
    }

    /* Go ahead and load all of the images we know we're going to need to
     * draw our game level. Then set init as the callback method, so that when
     * all of these images are properly loaded our game will start.
     */
    Resources.load([
        // 'images/stone-block.png',
        // 'images/water-block.png',
        // 'images/grass-block.png',
        // 'images/enemy-bug.png',
        // 'images/char-boy.png'
    ]);
    Resources.onReady(init);

    /* Assign the canvas' context object to the global variable (the window
     * object when run in a browser) so that developer's can use it more easily
     * from within their app.js files.
     */
    global.ctx = ctx;
})(this);<|endoftext|>


<commit_before>"use strict"

function init_events (config) {

	render_canvas.requestPointerLock = render_canvas.requestPointerLock || render_canvas.msRequestPointerLock || render_canvas.mozRequestPointerLock || render_canvas.webkitRequestPointerLock;

	render_canvas.addEventListener("click", function (evt) {
		if (config.is_game_paused && render_canvas.requestPointerLock) {
			render_canvas.requestPointerLock();
		}
		config.player.bindedFire(evt);
	}, false);

	function pointerLockChange () {

		if (document.pointerLockElement) {
			config.is_game_paused = false;
		} else {
			config.is_game_paused = true;
		}
	}
	document.addEventListener("pointerlockchange", pointerLockChange, false);
	document.addEventListener("mozpointerlockchange", pointerLockChange, false);
	document.addEventListener("webkitpointerlockchange", pointerLockChange, false);

	document.addEventListener("keydown", function (evt) {
		config.player.onKeyDown(evt.keyCode);
	}, false);

	document.addEventListener("keyup", function (evt) {
		config.player.onKeyUp(evt.keyCode);
	}, false);

	// Resize the babylon engine when the window is resized
	document.addEventListener("resize", function () {
		if (window.engine) {
			window.engine.resize();
		}
	}, false);
}
<commit_msg>fix click event<commit_after>"use strict"

function init_events (config) {

	document.requestPointerLock = document.requestPointerLock || document.msRequestPointerLock || document.mozRequestPointerLock || document.webkitRequestPointerLock;

	document.addEventListener("click", function (evt) {
		if (config.is_game_paused && document.requestPointerLock) {
			document.requestPointerLock();
		}
		config.player.bindedFire(evt);
	}, false);

	function pointerLockChange () {

		if (document.pointerLockElement) {
			config.is_game_paused = false;
		} else {
			config.is_game_paused = true;
		}
	}
	document.addEventListener("pointerlockchange", pointerLockChange, false);
	document.addEventListener("mozpointerlockchange", pointerLockChange, false);
	document.addEventListener("webkitpointerlockchange", pointerLockChange, false);

	document.addEventListener("keydown", function (evt) {
		config.player.onKeyDown(evt.keyCode);
	}, false);

	document.addEventListener("keyup", function (evt) {
		config.player.onKeyUp(evt.keyCode);
	}, false);

	// Resize the babylon engine when the window is resized
	document.addEventListener("resize", function () {
		if (window.engine) {
			window.engine.resize();
		}
	}, false);
}
<|endoftext|>


<commit_before>/**
 * @author Jan-Philipp Heine
 *
 * Class for selecting different attributes from the JSON File.
 * Actually the jFunk library is used but it can change in the future due to some difficulties.
 * Usage: jF("*[attribute=foo]",JSONFile).get() is equal to select * from JSONFile where attribute=foo
 */

/*
 * getManufacturerX(), getFuelTypeX(),getXX() are functions for filtering the JSON File. The JSON File is loaded by calling
 * the loadJSON() function and then stored as a variable. Afterwards the data is filtered and stored in a new variable.
 *
 * @return filtered JSONFile as a JavaScript Object
 */

var startDate;
var endDate;
var baseurl = "https://envirocar.org/api/stable/tracks?during="; //Global variable specifying the URL for the temporal filter contributed by the envirocar API
var allTracks = "https://envirocar.org/api/stable/tracks/";
var hyphen = "-";
var literalT = "T";
var literalZ = "Z";
var comma = ",";
var doublePoint = ":";

function getDateTime() {
	// Getting the values of the boxes where datetime is displayed
	startDate = $('#date-from').val();
	endDate = $('#date-to').val();

	// Check if a start and end date is specifyed. If not the user gets an alert
	if(startDate == '' || endDate == '') {
		alert("Kein Start- und / oder Endzeitpunkt ausgewählt");
	} else {
		// Storing the value of the date-from box in a variable
		var startDate = $('#date-from').val();

		// Storing the value of the date-to box in a variable
		var endDate = $('#date-to').val();

		alert("Sie haben den Startzeitpunkt " + startDate + " und den Endzeitpunkt " + endDate + " ausgewählt.");

		//Getting the literals from the date-from box and start building the first part of the string

		var year = startDate.charAt(6);
		var year1 = startDate.charAt(7);
		var year2 = startDate.charAt(8);
		var year3 = startDate.charAt(9);

		var baseurlYear = baseurl.concat(year, year1, year2, year3,hyphen);

		var month = startDate.charAt(3);
		var month1 = startDate.charAt(4);

		var baseurlYearMonth = baseurlYear.concat(month, month1, hyphen);

		var day = startDate.charAt(0);
		var day1 = startDate.charAt(1);

		var baseurlYearMonthDay = baseurlYearMonth.concat(day, day1, literalT);

		var hour = startDate.charAt(11);
		var hour1 = startDate.charAt(12);
		var minute = startDate.charAt(14);
		var minute1 = startDate.charAt(15);
		var seconds = "00";

		var baseurlStartDate = baseurlYearMonthDay.concat(hour, hour1, doublePoint, minute, minute1, doublePoint, seconds,literalZ , comma);
		//alert(baseurlStartDate) should be https://envirocar.org/api/stable/tracks?during=YYYY-MM-DDTHH:MM:SSZ,

		//Getting the literals from the date-to box and start building the second part of the string
		var endYear = endDate.charAt(6);
		var endYear1 = endDate.charAt(7);
		var endYear2 = endDate.charAt(8);
		var endYear3 = endDate.charAt(9);

		var baseurlEndDateYear = baseurlStartDate.concat(endYear, endYear1, endYear2, endYear3,hyphen);

		var endMonth = endDate.charAt(3);
		var endMonth1 = endDate.charAt(4);

		var baseurlEndDateYearMonth = baseurlEndDateYear.concat(endMonth, endMonth1, hyphen);

		var endDay = endDate.charAt(0);
		var endDay1 = endDate.charAt(1);

		var baseurlEndDateYearMonthDay = baseurlEndDateYearMonth.concat(endDay, endDay1, literalT);

		var endHour = endDate.charAt(11);
		var endHour1 = endDate.charAt(12);
		var endMinute = endDate.charAt(14);
		var endMinute1 = endDate.charAt(15);
		var seconds = "00";

		var baseurlEndDate = baseurlEndDateYearMonthDay.concat(endHour, endHour1, doublePoint, endMinute, endMinute1, doublePoint, seconds,literalZ);
		//alert(baseurlEndDate) should be https://envirocar.org/api/stable/tracks?during=YYYY-MM-DDTHH:MM:SSZ,YYYY-MM-DDTHH:MM:SSZ

		var requestURL = baseurlEndDate;

		// alert("Die URL für die RESTAbfrage " + requestURL);

		// Requesting the JSON File from envirocar

		var json = (function () {
			var json = null;
			$.ajax({
				'async': false,
				'url': requestURL,
				'dataType': "json",
				// If request succeeded the callback function stores the requested JSON to var = json
				'success': function (data) {json = data;},
				'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
			});

			// returns the object
			return json;
		})();

		// stores the returned object in the variable JSONFile.
		var JSONFile = json;

		// alert("Das ist der abgerufene JSONFile " + JSON.stringify(JSONFile));

		// Loops through the requested JSONFile and gets with the use of the trackID the additional information for all specified tracks

		$.each(JSONFile.tracks, function (key, value) {
			trackURL = allTracks.concat(value.id);

			var json = (function () {
				var json = null;
				$.ajax({
					'async': false,
					'url': trackURL,
					'dataType': "json",
					// If request succeeded the callback function stores the requested JSON to var = json
					'success': function (data) {json = data;},
					'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
				});

				// returns the object
				return json;
			})();

			// The requested JSON File is cast to a string
			var jsonTrackData = JSON.stringify(json);

			// The JSON File is now parsed and could be entered
			var jsonTrackDataObj = jQuery.parseJSON(jsonTrackData);

			// Text for the dropdown menu
            $("#trackSelectionList").append($('<option></option>').val(value.id).html(jsonTrackDataObj.properties.sensor.properties.manufacturer + " " + jsonTrackDataObj.properties.sensor.properties.model + " TrackID: " + value.id));
		});

		// onChange alert with more specific car data
		$('#trackSelectionList').change(function () {
			trackURL = allTracks.concat($(this).val());

			var json = (function () {
				var json = null;
				$.ajax({
					'async': false,
					// Requesting a local file due to the cross domain constrait explained above
					'url': trackURL,
					'dataType': "json",
					// If request succeeded the callback function stores the requested JSON to var = json
					'success': function (data) {json = data;},
					'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
				});

				// returns the object
				return json;
			})();

			var jsonTrackData = JSON.stringify(json);

			var jsonTrackDataObj = jQuery.parseJSON(jsonTrackData);

			alert("Manufacturer: " + jsonTrackDataObj.properties.sensor.properties.manufacturer + "\n"
			+ "ModelType: " + jsonTrackDataObj.properties.sensor.properties.model + "\n"
			+ "FuelType: " + jsonTrackDataObj.properties.sensor.properties.fuelType + "\n"
			+ "ConstructionYear: " + jsonTrackDataObj.properties.sensor.properties.constructionYear);
		});

		// testParsing(JSONFile);
		// return JSONFile;
	}
}

function getBBox() {
	pointNorthEast = rectangle.getBounds().getNorthEast().toString();
	pointSouthWest = rectangle.getBounds().getSouthWest().toString();

	// alert("NE: " + pointNorthEast + "\n" + "SW: " + pointSouthWest); // TODO delete before release

	pointNorthEastX = pointNorthEast.slice(1,18);
	pointNorthEastY = pointNorthEast.slice(20,37);
	pointSouthWestX = pointSouthWest.slice(1,18);
	pointSouthWestY = pointSouthWest.slice(20,37);

	var pnex = pointNorthEastX;
	var pney = pointNorthEastY;
	var pswx = pointSouthWestX;
	var pswy = pointSouthWestY;

	var BBoxURL = baseurlBBox.concat(pswx, comma, pswy, comma, pnex, comma, pney);

	// https://envirocar.org/api/stable/tracks?bbox=51.94526347230317,7.626482342364511,51.95054506839408,7.603436801737075
	// findet keine Tracks
	alert(BBoxURL);
}

// TODO delete function before release
// function testBBox(bounds) {
//
	// var point1 = map.getBounds().getNorthEast();
	// var point2 = map.getBounds().getSouthWest();
//
	// alert(bounds);

	// var jsonTrackIDs = JSON.stringify(JSONFile);
//
	// var objtest = jQuery.parseJSON(jsonTrackIDs);
//
	// var track = objtest.tracks[0].id;
//
	// var allTracks = "https://envirocar.org/api/stable/tracks/";
//
	// var trackURL = allTracks.concat(track);
//
	// alert(trackURL);
//
	// var json = (function () {
//
//
			// var json = null;
			// $.ajax({
				// 'async': false,
				// // Requesting a local file due to the cross domain constrait explained above
				// 'url': trackURL,
				// 'dataType': "json",
				// // If request succeeded the callback function stores the requested JSON to var = json
				// 'success': function (data) {json = data;},
				// 'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
			// });
//
			// // returns the object
			// return json;
		// })();
//
	// var jsonTrackData = JSON.stringify(json);
//
	// var jsonTrackDataObj = jQuery.parseJSON(jsonTrackData);
//
	// alert(jsonTrackDataObj.properties.sensor.properties.manufacturer);

	// alert(JSON.stringify(JSONFile));
//}

// old stuff

// Get measurements with manufacturer = BMW
function getManufacturerBMW() {
	// Load JSON File via AJAX Request from URL
    json = loadJSON();

    // Filtering JSONFile
    var BMW = jF("*[manufacturer=BMW]",json).get();

	// document.getElementById("ManufacturerBMW").innerHTML = JSON.stringify(BMW);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(BMW);

	// Returns filtered JSONFile
	return BMW;
}

// Get measurements with manufacturer = VW
function getManufacturerVW() {
    json = loadJSON();

    var VW = jF("*[manufacturer=VW]",json).get();

	// document.getElementById("ManufacturerVW").innerHTML = JSON.stringify(VW);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(VW);

	return VW;
}

// Get measurements with fuel type = Diesel
function getFuelTypeDiesel() {
	json = loadJSON();

    var diesel=jF("*[fuelType=diesel]",json).get();

	// document.getElementById("FuelTypeDiesel").innerHTML = JSON.stringify(diesel);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(diesel);

	return diesel;
}

// Get measurements with manufacturer = BMW and fuel type = Diesel
function getDIESELVW() {
	json = getFuelTypeDiesel();

	var dieselVW = jF("*[manufacturer=VW]",json).get();

	// document.getElementById("FuelTypeDiesel").innerHTML = JSON.stringify(dieselVW);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(dieselVW);

	return dieselVW;
}
<commit_msg>Add translation for alert in filter.js<commit_after>/**
 * @author Jan-Philipp Heine
 *
 * Class for selecting different attributes from the JSON File.
 * Actually the jFunk library is used but it can change in the future due to some difficulties.
 * Usage: jF("*[attribute=foo]",JSONFile).get() is equal to select * from JSONFile where attribute=foo
 */

/*
 * getManufacturerX(), getFuelTypeX(),getXX() are functions for filtering the JSON File. The JSON File is loaded by calling
 * the loadJSON() function and then stored as a variable. Afterwards the data is filtered and stored in a new variable.
 *
 * @return filtered JSONFile as a JavaScript Object
 */

var startDate;
var endDate;
var baseurl = "https://envirocar.org/api/stable/tracks?during="; //Global variable specifying the URL for the temporal filter contributed by the envirocar API
var allTracks = "https://envirocar.org/api/stable/tracks/";
var hyphen = "-";
var literalT = "T";
var literalZ = "Z";
var comma = ",";
var doublePoint = ":";

function getDateTime() {
	// Getting the values of the boxes where datetime is displayed
	startDate = $('#date-from').val();
	endDate = $('#date-to').val();

	// Check if a start and end date is specifyed. If not the user gets an alert
	if (startDate == '' || endDate == '') {
		if (getParam('lang') == 'en') {
			alert('No start and / or end date selected')
		} else {
			alert('Kein Start- und / oder Endzeitpunkt ausgewählt');
		}
	} else {
		// Storing the value of the date-from box in a variable
		var startDate = $('#date-from').val();

		// Storing the value of the date-to box in a variable
		var endDate = $('#date-to').val();

		alert("Sie haben den Startzeitpunkt " + startDate + " und den Endzeitpunkt " + endDate + " ausgewählt.");

		//Getting the literals from the date-from box and start building the first part of the string

		var year = startDate.charAt(6);
		var year1 = startDate.charAt(7);
		var year2 = startDate.charAt(8);
		var year3 = startDate.charAt(9);

		var baseurlYear = baseurl.concat(year, year1, year2, year3,hyphen);

		var month = startDate.charAt(3);
		var month1 = startDate.charAt(4);

		var baseurlYearMonth = baseurlYear.concat(month, month1, hyphen);

		var day = startDate.charAt(0);
		var day1 = startDate.charAt(1);

		var baseurlYearMonthDay = baseurlYearMonth.concat(day, day1, literalT);

		var hour = startDate.charAt(11);
		var hour1 = startDate.charAt(12);
		var minute = startDate.charAt(14);
		var minute1 = startDate.charAt(15);
		var seconds = "00";

		var baseurlStartDate = baseurlYearMonthDay.concat(hour, hour1, doublePoint, minute, minute1, doublePoint, seconds,literalZ , comma);
		//alert(baseurlStartDate) should be https://envirocar.org/api/stable/tracks?during=YYYY-MM-DDTHH:MM:SSZ,

		//Getting the literals from the date-to box and start building the second part of the string
		var endYear = endDate.charAt(6);
		var endYear1 = endDate.charAt(7);
		var endYear2 = endDate.charAt(8);
		var endYear3 = endDate.charAt(9);

		var baseurlEndDateYear = baseurlStartDate.concat(endYear, endYear1, endYear2, endYear3,hyphen);

		var endMonth = endDate.charAt(3);
		var endMonth1 = endDate.charAt(4);

		var baseurlEndDateYearMonth = baseurlEndDateYear.concat(endMonth, endMonth1, hyphen);

		var endDay = endDate.charAt(0);
		var endDay1 = endDate.charAt(1);

		var baseurlEndDateYearMonthDay = baseurlEndDateYearMonth.concat(endDay, endDay1, literalT);

		var endHour = endDate.charAt(11);
		var endHour1 = endDate.charAt(12);
		var endMinute = endDate.charAt(14);
		var endMinute1 = endDate.charAt(15);
		var seconds = "00";

		var baseurlEndDate = baseurlEndDateYearMonthDay.concat(endHour, endHour1, doublePoint, endMinute, endMinute1, doublePoint, seconds,literalZ);
		//alert(baseurlEndDate) should be https://envirocar.org/api/stable/tracks?during=YYYY-MM-DDTHH:MM:SSZ,YYYY-MM-DDTHH:MM:SSZ

		var requestURL = baseurlEndDate;

		// alert("Die URL für die RESTAbfrage " + requestURL);

		// Requesting the JSON File from envirocar

		var json = (function () {
			var json = null;
			$.ajax({
				'async': false,
				'url': requestURL,
				'dataType': "json",
				// If request succeeded the callback function stores the requested JSON to var = json
				'success': function (data) {json = data;},
				'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
			});

			// returns the object
			return json;
		})();

		// stores the returned object in the variable JSONFile.
		var JSONFile = json;

		// alert("Das ist der abgerufene JSONFile " + JSON.stringify(JSONFile));

		// Loops through the requested JSONFile and gets with the use of the trackID the additional information for all specified tracks

		$.each(JSONFile.tracks, function (key, value) {
			trackURL = allTracks.concat(value.id);

			var json = (function () {
				var json = null;
				$.ajax({
					'async': false,
					'url': trackURL,
					'dataType': "json",
					// If request succeeded the callback function stores the requested JSON to var = json
					'success': function (data) {json = data;},
					'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
				});

				// returns the object
				return json;
			})();

			// The requested JSON File is cast to a string
			var jsonTrackData = JSON.stringify(json);

			// The JSON File is now parsed and could be entered
			var jsonTrackDataObj = jQuery.parseJSON(jsonTrackData);

			// Text for the dropdown menu
            $("#trackSelectionList").append($('<option></option>').val(value.id).html(jsonTrackDataObj.properties.sensor.properties.manufacturer + " " + jsonTrackDataObj.properties.sensor.properties.model + " TrackID: " + value.id));
		});

		// onChange alert with more specific car data
		$('#trackSelectionList').change(function () {
			trackURL = allTracks.concat($(this).val());

			var json = (function () {
				var json = null;
				$.ajax({
					'async': false,
					// Requesting a local file due to the cross domain constrait explained above
					'url': trackURL,
					'dataType': "json",
					// If request succeeded the callback function stores the requested JSON to var = json
					'success': function (data) {json = data;},
					'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
				});

				// returns the object
				return json;
			})();

			var jsonTrackData = JSON.stringify(json);

			var jsonTrackDataObj = jQuery.parseJSON(jsonTrackData);

			alert("Manufacturer: " + jsonTrackDataObj.properties.sensor.properties.manufacturer + "\n"
			+ "ModelType: " + jsonTrackDataObj.properties.sensor.properties.model + "\n"
			+ "FuelType: " + jsonTrackDataObj.properties.sensor.properties.fuelType + "\n"
			+ "ConstructionYear: " + jsonTrackDataObj.properties.sensor.properties.constructionYear);
		});

		// testParsing(JSONFile);
		// return JSONFile;
	}
}

function getBBox() {
	pointNorthEast = rectangle.getBounds().getNorthEast().toString();
	pointSouthWest = rectangle.getBounds().getSouthWest().toString();

	// alert("NE: " + pointNorthEast + "\n" + "SW: " + pointSouthWest); // TODO delete before release

	pointNorthEastX = pointNorthEast.slice(1,18);
	pointNorthEastY = pointNorthEast.slice(20,37);
	pointSouthWestX = pointSouthWest.slice(1,18);
	pointSouthWestY = pointSouthWest.slice(20,37);

	var pnex = pointNorthEastX;
	var pney = pointNorthEastY;
	var pswx = pointSouthWestX;
	var pswy = pointSouthWestY;

	var BBoxURL = baseurlBBox.concat(pswx, comma, pswy, comma, pnex, comma, pney);

	// https://envirocar.org/api/stable/tracks?bbox=51.94526347230317,7.626482342364511,51.95054506839408,7.603436801737075
	// findet keine Tracks
	alert(BBoxURL);
}

// TODO delete function before release
// function testBBox(bounds) {
//
	// var point1 = map.getBounds().getNorthEast();
	// var point2 = map.getBounds().getSouthWest();
//
	// alert(bounds);

	// var jsonTrackIDs = JSON.stringify(JSONFile);
//
	// var objtest = jQuery.parseJSON(jsonTrackIDs);
//
	// var track = objtest.tracks[0].id;
//
	// var allTracks = "https://envirocar.org/api/stable/tracks/";
//
	// var trackURL = allTracks.concat(track);
//
	// alert(trackURL);
//
	// var json = (function () {
//
//
			// var json = null;
			// $.ajax({
				// 'async': false,
				// // Requesting a local file due to the cross domain constrait explained above
				// 'url': trackURL,
				// 'dataType': "json",
				// // If request succeeded the callback function stores the requested JSON to var = json
				// 'success': function (data) {json = data;},
				// 'error': function(jqXHR, textStatus, errorThrown) {alert('Error ' + errorThrown);}
			// });
//
			// // returns the object
			// return json;
		// })();
//
	// var jsonTrackData = JSON.stringify(json);
//
	// var jsonTrackDataObj = jQuery.parseJSON(jsonTrackData);
//
	// alert(jsonTrackDataObj.properties.sensor.properties.manufacturer);

	// alert(JSON.stringify(JSONFile));
//}

// old stuff

// Get measurements with manufacturer = BMW
function getManufacturerBMW() {
	// Load JSON File via AJAX Request from URL
    json = loadJSON();

    // Filtering JSONFile
    var BMW = jF("*[manufacturer=BMW]",json).get();

	// document.getElementById("ManufacturerBMW").innerHTML = JSON.stringify(BMW);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(BMW);

	// Returns filtered JSONFile
	return BMW;
}

// Get measurements with manufacturer = VW
function getManufacturerVW() {
    json = loadJSON();

    var VW = jF("*[manufacturer=VW]",json).get();

	// document.getElementById("ManufacturerVW").innerHTML = JSON.stringify(VW);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(VW);

	return VW;
}

// Get measurements with fuel type = Diesel
function getFuelTypeDiesel() {
	json = loadJSON();

    var diesel=jF("*[fuelType=diesel]",json).get();

	// document.getElementById("FuelTypeDiesel").innerHTML = JSON.stringify(diesel);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(diesel);

	return diesel;
}

// Get measurements with manufacturer = BMW and fuel type = Diesel
function getDIESELVW() {
	json = getFuelTypeDiesel();

	var dieselVW = jF("*[manufacturer=VW]",json).get();

	// document.getElementById("FuelTypeDiesel").innerHTML = JSON.stringify(dieselVW);
	document.getElementById("simplyatest").innerHTML = JSON.stringify(dieselVW);

	return dieselVW;
}
<|endoftext|>


<commit_before><commit_msg>chore(lint): lint<commit_after><|endoftext|>


<commit_before>function initPage() {

	// Enlarge logAccessConfigId combobox if necessary
	if ($("#logAccessConfigId").width() < 200) {
		$("#logAccessConfigId").width(200);
	}

	// Process logAccessConfigId combobox change
	$("#logAccessConfigId").change(function(){
		window.location = "../" + $(this).val() + "/list";
	});

	// Placeholder in 'cmd' input
	$("#cmd").placeholder();

	// Encoding buttons
	var checkedEncodingId = $("input[name=encoding][checked]").attr("id");
	$("label[for=" + checkedEncodingId + "]").addClass("active");

	// DisplayType buttons
	var checkedDisplayTypeId = $("input[name=displayType][checked]").attr("id");
	$("label[for=" + checkedDisplayTypeId + "]").addClass("active");

	// Auto-Submit command form
	$("#downloadButton").click(downloadCommandResult);
	$("#executeButton").click(submitCommandForm);
	$("#commandForm input:radio").change(submitCommandForm);

	// Auto-adapt RAW content width
	if ($("pre").length == 1 && $("pre").width() < $(window).width()) {
		$("pre").addClass("nofloat");
	}

	// Render results table
	var resultsSize = $("#resultsSize").val();
	if (resultsSize && resultsSize < 1500) {
		$("#resultsTable").dataTable({
			bPaginate: false,
			bStateSave: true,
			fnStateSaveParams: function (oSettings, oData) {
				oData.oSearch.sSearch = "";
			}
		});
	}
}

function submitCommandForm() {
	if ($("#cmd").val() != "") {
		$("#commandForm").submit();
	}
	else {
		$("#executeButton").blur();
	}
}

function downloadCommandResult() {
	$(this).blur();
	if ($("#cmd").val() != "") {
		var fileName = $("ul.breadcrumb li.active").text();
		fileName = fileName.replace(/\.tar\.gz$|\.gz$/, ".log").replace(/\.log\.log/, ".log");
		window.location = "download?" + $("#cmd").serialize() + "&fileName=" + escape(fileName);
	}
}

$(initPage);
<commit_msg>update datatables label messages<commit_after>function initPage() {

	// Enlarge logAccessConfigId combobox if necessary
	if ($("#logAccessConfigId").width() < 200) {
		$("#logAccessConfigId").width(200);
	}

	// Process logAccessConfigId combobox change
	$("#logAccessConfigId").change(function(){
		window.location = "../" + $(this).val() + "/list";
	});

	// Placeholder in 'cmd' input
	$("#cmd").placeholder();

	// Encoding buttons
	var checkedEncodingId = $("input[name=encoding][checked]").attr("id");
	$("label[for=" + checkedEncodingId + "]").addClass("active");

	// DisplayType buttons
	var checkedDisplayTypeId = $("input[name=displayType][checked]").attr("id");
	$("label[for=" + checkedDisplayTypeId + "]").addClass("active");

	// Auto-Submit command form
	$("#downloadButton").click(downloadCommandResult);
	$("#executeButton").click(submitCommandForm);
	$("#commandForm input:radio").change(submitCommandForm);

	// Auto-adapt RAW content width
	if ($("pre").length == 1 && $("pre").width() < $(window).width()) {
		$("pre").addClass("nofloat");
	}

	// Render results table
	var resultsSize = $("#resultsSize").val();
	if (resultsSize && resultsSize < 1500) {
		$("#resultsTable").dataTable({
			bPaginate: false,
			bStateSave: true,
			fnStateSaveParams: function (oSettings, oData) {
				oData.oSearch.sSearch = "";
			},
			language: {
			    info: "Showing _TOTAL_ entries",
			    infoEmpty: "Showing 0 entries",
			    sEmptyTable: "No entries to show"
			  }
		});
	}
}

function submitCommandForm() {
	if ($("#cmd").val() != "") {
		$("#commandForm").submit();
	}
	else {
		$("#executeButton").blur();
	}
}

function downloadCommandResult() {
	$(this).blur();
	if ($("#cmd").val() != "") {
		var fileName = $("ul.breadcrumb li.active").text();
		fileName = fileName.replace(/\.tar\.gz$|\.gz$/, ".log").replace(/\.log\.log/, ".log");
		window.location = "download?" + $("#cmd").serialize() + "&fileName=" + escape(fileName);
	}
}

$(initPage);
<|endoftext|>


<commit_before>/********************************************************************
*
* Filename:		base.js
* Description:	Creates the 'base' class.
*
********************************************************************/

(function(window){

var base = function ( args ) {

		if ( this instanceof arguments.callee ) {

			this.init.apply( this, args.callee ? args : arguments );

			return this;

		} else {

			return new arguments.callee( arguments );

		}

	},

	ArrayProto = Array.prototype,

	nativeForEach = ArrayProto.forEach,

	slice = ArrayProto.slice,

	breaker = {},

	each = function(obj, iterator, context) {

		if (obj == null){

			return;

		}
	    if (nativeForEach && obj.forEach === nativeForEach) {

			obj.forEach(iterator, context);

	    } else if (obj.length === +obj.length) {

			for (var i = 0, l = obj.length; i < l; i++) {

				if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;

			}

	    } else {

			for (var key in obj) {

				if (_.has(obj, key)) {

					if (iterator.call(context, obj[key], key, obj) === breaker){

						return;

					}

				}

			}

	    }

	},

	extend = base.extend = function(obj) {

		each(slice.call(arguments, 1), function(source) {

			for (var prop in source) {

				obj[prop] = source[prop];

			}

		});

		return obj;
	};

	extend(base, {

		addStaticMethods : function addStaticMethods(methods){
			base.extend(this, methods);
		},

		addInstanceMethods : function addInstanceMethods(methods){
			base.extend(this.prototype, methods);
		},

		createChild : function createChild(){

			var child = function base( args ){

				if ( this instanceof arguments.callee ) {

					this.init.apply( this, args.callee ? args : arguments );

					return this;

				} else {

					return new arguments.callee( arguments );

				}
			};

			base.extend(child, this);
			base.extend(child.prototype,  this.prototype);

			return child;

		}

	});

	base.addInstanceMethods({

		init : function baseInit( config ){

			return this;

		}

	});

	window.base = base;

}(window));

	<commit_msg>Updated to add the addStaticProperties and addInstanceProperties methods<commit_after>/********************************************************************
*
* Filename:		base.js
* Description:	Creates the 'base' class.
*
********************************************************************/

(function(window){

var base = function ( args ) {

		if ( this instanceof arguments.callee ) {

			this.init.apply( this, args.callee ? args : arguments );

			return this;

		} else {

			return new arguments.callee( arguments );

		}

	},

	ArrayProto = Array.prototype,

	nativeForEach = ArrayProto.forEach,

	slice = ArrayProto.slice,

	breaker = {},

	each = function(obj, iterator, context) {

		if (obj == null){

			return;

		}
	    if (nativeForEach && obj.forEach === nativeForEach) {

			obj.forEach(iterator, context);

	    } else if (obj.length === +obj.length) {

			for (var i = 0, l = obj.length; i < l; i++) {

				if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;

			}

	    } else {

			for (var key in obj) {

				if (_.has(obj, key)) {

					if (iterator.call(context, obj[key], key, obj) === breaker){

						return;

					}

				}

			}

	    }

	},

	extend = base.extend = function(obj) {

		each(slice.call(arguments, 1), function(source) {

			for (var prop in source) {

				obj[prop] = source[prop];

			}

		});

		return obj;
	};

	extend(base, {

		addStaticMethods : function addStaticMethods(methods){
			base.extend(this, methods);
		},

		addInstanceMethods : function addInstanceMethods(methods){
			base.extend(this.prototype, methods);
		},

		createChild : function createChild(){

			var child = function base( args ){

				if ( this instanceof arguments.callee ) {

					this.init.apply( this, args.callee ? args : arguments );

					return this;

				} else {

					return new arguments.callee( arguments );

				}
			};

			base.extend(child, this);
			base.extend(child.prototype,  this.prototype);

			return child;

		}

	});

	extend(base, {
    	addStaticProperties: base.addStaticMethods,
		addInstanceProperties: base.addInstanceMethods
	});

	base.addInstanceMethods({

		init : function baseInit( config ){

			return this;

		}

	});

	window.base = base;

}(window));

	<|endoftext|>