<commit_before>/**
 * Copyright 2015 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.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.solinea.com/goldstone/LICENSE.pdf
 *
 * 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 expressed or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var LoginPageView = Backbone.View.extend({

    initialize: function(options) {
        this.options = options || {};
        this.defaults = _.clone(this.defaults);
        this.el = options.el;
        this.render();
        this.addHandlers();
    },

    addHandlers: function() {
        var self = this;

        $('.login-form').on('submit', function(e) {
            e.preventDefault();
            self.submitLogin($(this).serialize());
        });
    },

    submitLogin: function(input) {
        var self = this;

        // console.log('submitLogin received: ', input);
        $.post('/accounts/login', input, function() {})
            .done(function(success) {

                // store the auth token
                self.storeAuthToken(success.auth_token);

                // and add a message to the top of the screen that logs what
                // is returned from the call
                // and clear that message after 2 seconds
                self.displayInfoMessage('Authorization Successful');

                self.redirectPostSuccessfulAuth();

            })
            .fail(function(fail) {

                // and add a message to the top of the screen that logs what
                // is returned from the call
                // and clear that message after 2 seconds
                self.displayInfoMessage(fail.responseJSON.non_field_errors[0]);
            });
    },

    storeAuthToken: function(token) {
        localStorage.setItem('userToken', token);
    },

    displayInfoMessage: function(text) {
        $('.alert-info').show();
        $('.alert-info').text(text);

        setTimeout(function() {
            $('.alert-info').hide();
        }, 2000);
    },

    redirectPostSuccessfulAuth: function() {

        // if there was a previously visited page that
        // had redirected to the login page due to lack
        // of credentials, redirect back to that page
        if (location.hash && location.hash.length > 0) {
            locationhref = '/' + location.hash.slice(1);
        } else {

            // or just redirect to /discover
            locationhref = '/';
        }

        location.href = locationhref;

    },

    render: function() {
        this.$el.html(this.template());
        return this;
    },

    template: _.template('' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
Goldstone
' +
        '
' +
        '<form class="login-form">' +
        '
Please sign in
' +
        'Username' +
        '<input name="username" type="text" class="form-control" placeholder="Username" required autofocus>' +
        'Password' +
        '<input name="password" type="password" class="form-control" placeholder="Password" required>
' +
        '<button name="submit" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>' +
        '</form>' +
        '
forgot username or password?
' +
        '
' +
        '
' +
        '
'
    )

});
<commit_msg>Updates successful login message and increases time of success message to 3 seconds.<commit_after>/**
 * Copyright 2015 Solinea, Inc.
 *
 * Licensed under the Solinea Software License Agreement (goldstone),
 * Version 1.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.solinea.com/goldstone/LICENSE.pdf
 *
 * 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 expressed or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var LoginPageView = Backbone.View.extend({

    initialize: function(options) {
        this.options = options || {};
        this.defaults = _.clone(this.defaults);
        this.el = options.el;
        this.render();
        this.addHandlers();
    },

    addHandlers: function() {
        var self = this;

        $('.login-form').on('submit', function(e) {
            e.preventDefault();
            self.submitLogin($(this).serialize());
        });
    },

    submitLogin: function(input) {
        var self = this;

        // console.log('submitLogin received: ', input);
        $.post('/accounts/login', input, function() {})
            .done(function(success) {

                // store the auth token
                self.storeAuthToken(success.auth_token);

                // and add a message to the top of the screen that logs what
                // is returned from the call
                // and clear that message after 2 seconds
                self.displayInfoMessage('Authorization Successful, redirecting to goldstone');

                self.redirectPostSuccessfulAuth();

            })
            .fail(function(fail) {

                // and add a message to the top of the screen that logs what
                // is returned from the call
                // and clear that message after 2 seconds
                self.displayInfoMessage(fail.responseJSON.non_field_errors[0]);
            });
    },

    storeAuthToken: function(token) {
        localStorage.setItem('userToken', token);
    },

    displayInfoMessage: function(text) {
        $('.alert-info').show();
        $('.alert-info').text(text);

        setTimeout(function() {
            $('.alert-info').hide();
        }, 3000);
    },

    redirectPostSuccessfulAuth: function() {

        // if there was a previously visited page that
        // had redirected to the login page due to lack
        // of credentials, redirect back to that page
        if (location.hash && location.hash.length > 0) {
            locationhref = '/' + location.hash.slice(1);
        } else {

            // or just redirect to /discover
            locationhref = '/';
        }

        location.href = locationhref;

    },

    render: function() {
        this.$el.html(this.template());
        return this;
    },

    template: _.template('' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
Goldstone
' +
        '
' +
        '<form class="login-form">' +
        '
Please sign in
' +
        'Username' +
        '<input name="username" type="text" class="form-control" placeholder="Username" required autofocus>' +
        'Password' +
        '<input name="password" type="password" class="form-control" placeholder="Password" required>
' +
        '<button name="submit" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>' +
        '</form>' +
        '
forgot username or password?
' +
        '
' +
        '
' +
        '
'
    )

});
<|endoftext|>


<commit_before>/*
---

name: View.Scroll

description: Provide a view that scrolls when the content is larger that the
             window.

license: MIT-style license.

authors:
	- Jean-Philippe Dery (jeanphilippe.dery@gmail.com)

requires:
	- View

provides:
	- View.Scroll

...
*/

Moobile.View.Scroll = new Class({

	Static: {
		scrollers: 0
	},

	Extends: Moobile.View,

	contentSize: null,

	scroller: null,

	scrollerUpdateInterval: null,

	scrolled: null,

	setup: function() {
		this.parent();
		this.attachScroller();
		return this;
	},

	destroy: function() {
		this.detachScroller();
		this.parent();
		return this;
	},

	attachScroller: function() {
		if (++Moobile.View.Scroll.scrollers == 1) document.addEventListener('touchmove', this.onDocumentTouchMove);
		return this;
	},

	detachScroller: function() {
		if (--Moobile.View.Scroll.scrollers == 0) document.removeEventListener('touchmove', this.onDocumentTouchMove);
		return this;
	},

	createScroller: function() {
		return new iScroll(this.wrapper, { desktopCompatibility: true, hScroll: false, vScroll: true });
	},

	enableScroller: function() {
		if (this.scroller == null) {
			this.scroller = this.createScroller();
			this.updateScroller();
			this.updateScrollerAutomatically(true);
			if (this.scrolled) this.scroller.scrollTo(0, -this.scrolled);
		}
		return this;
	},

	disableScroller: function() {
		if (this.scroller) {
			this.updateScrollerAutomatically(false);
			this.scrolled = this.content.getStyle('transform');
			this.scrolled = this.scrolled.match(/translate3d\(-*(\d+)px, -*(\d+)px, -*(\d+)px\)/)
			this.scrolled = this.scrolled[2];
			this.scroller.destroy();
			this.scroller = null;
		}
		return this;
	},

	updateScroller: function() {
		if (this.scroller) {
			if (this.contentSize != this.content.getScrollSize().y) {
				this.contentSize = this.content.getScrollSize().y;
				var extent = this.getContentExtent();
				this.wrapper.setStyle('overflow', 'visible');
				this.wrapper.setStyle('height', extent.y);
				this.wrapper.setStyle('min-height', extent.y);
				this.content.setStyle('min-height', extent.y);
				this.scroller.refresh();
			}
		}
		return this;
	},

	updateScrollerAutomatically: function(automatically) {
		clearInterval(this.scrollerUpdateInterval);
		if (automatically) this.scrollerUpdateInterval = this.updateScroller.periodical(250, this);
		return this;
	},

	willEnter: function() {
		this.enableScroller();
		return this.parent();
	},

	didLeave: function() {
		this.disableScroller();
		return this.parent();
	},

	onDocumentTouchMove: function(e) {
		e.preventDefault();
	}

});<commit_msg>Fixed an issue where the content could not overflow under the navigation bar.<commit_after>/*
---

name: View.Scroll

description: Provide a view that scrolls when the content is larger that the
             window.

license: MIT-style license.

authors:
	- Jean-Philippe Dery (jeanphilippe.dery@gmail.com)

requires:
	- View

provides:
	- View.Scroll

...
*/

Moobile.View.Scroll = new Class({

	Static: {
		scrollers: 0
	},

	Extends: Moobile.View,

	contentSize: null,

	scroller: null,

	scrollerUpdateInterval: null,

	scrolled: null,

	setup: function() {
		this.parent();
		this.attachScroller();
		return this;
	},

	destroy: function() {
		this.detachScroller();
		this.parent();
		return this;
	},

	attachScroller: function() {
		if (++Moobile.View.Scroll.scrollers == 1) document.addEventListener('touchmove', this.onDocumentTouchMove);
		return this;
	},

	detachScroller: function() {
		if (--Moobile.View.Scroll.scrollers == 0) document.removeEventListener('touchmove', this.onDocumentTouchMove);
		return this;
	},

	createScroller: function() {
		return new iScroll(this.wrapper, { desktopCompatibility: true, hScroll: false, vScroll: true });
	},

	enableScroller: function() {
		if (this.scroller == null) {
			this.scroller = this.createScroller();
			this.wrapper.setStyle('overflow', 'visible');
			this.updateScroller();
			this.updateScrollerAutomatically(true);
			if (this.scrolled) this.scroller.scrollTo(0, -this.scrolled);
		}
		return this;
	},

	disableScroller: function() {
		if (this.scroller) {
			this.updateScrollerAutomatically(false);
			this.scrolled = this.content.getStyle('transform');
			this.scrolled = this.scrolled.match(/translate3d\(-*(\d+)px, -*(\d+)px, -*(\d+)px\)/)
			this.scrolled = this.scrolled[2];
			this.scroller.destroy();
			this.scroller = null;
		}
		return this;
	},

	updateScroller: function() {
		if (this.scroller) {
			if (this.contentSize != this.content.getScrollSize().y) {
				this.contentSize = this.content.getScrollSize().y;
				var extent = this.getContentExtent();
				this.wrapper.setStyle('height', extent.y);
				this.wrapper.setStyle('min-height', extent.y);
				this.content.setStyle('min-height', extent.y);
				this.scroller.refresh();
			}
		}
		return this;
	},

	updateScrollerAutomatically: function(automatically) {
		clearInterval(this.scrollerUpdateInterval);
		if (automatically) this.scrollerUpdateInterval = this.updateScroller.periodical(250, this);
		return this;
	},

	willEnter: function() {
		this.enableScroller();
		return this.parent();
	},

	didLeave: function() {
		this.disableScroller();
		return this.parent();
	},

	onDocumentTouchMove: function(e) {
		e.preventDefault();
	}

});<|endoftext|>


<commit_before>var cacaPalavras = function(numeroDeLinhas, numeroDeColunas, podeCruzar, chancesParaReverso) {
	var palavras = [],
		letras = [],
		letrasParaPreenchimento = []
		letrasTudoPreenchido = [];

	var letraVazia = " ";

	for(var i = 0; i < numeroDeLinhas; i++) {
		letras[i] = [];

		for(var j = 0; j < numeroDeColunas; j++) {
			letras[i][j] = letraVazia;
		}
	}

	var getCopiaLetras = function() {
		var retorno = [];

		for(var i = 0; i < letras.length; i++)
			retorno.push(letras[i].slice());

		return retorno;
	};

	this.getShow = function getShow(getLetraCallback, preencherEspacoEmBranco, caracteresEsquerda, caracteresDireita, mostrarLinhas) {
		var output = "";

		for(var i = 0; i < numeroDeLinhas; i++) {
			output += mostrarLinhas ? ("000" + (i + 1)).slice(("000" + (i + 1)).length - 3, ("000" + (i + 1)).length) + ": " : "";

			for(var j = 0; j < numeroDeColunas; j++) {
				output +=
					((caracteresEsquerda === undefined) ? "" : caracteresEsquerda) +
					((getLetraCallback(i, j).trim() === "") ? (preencherEspacoEmBranco === undefined ? "+" : preencherEspacoEmBranco) : getLetraCallback(i, j)) +
					((caracteresDireita === undefined) ? "" : caracteresDireita);
			}

			output += "\r\n";
		}

		return output.toUpperCase();
	};

	this.getShowPalavras = function() {
		var output = "";

		for(var i = 0; i < palavras.length; i++) {
			output += palavras[i] + (i < palavras.length - 1 ? "\n" : "");
		}

		return output;
	};

	this.preencherLetrasRestantes = function(preenchimento) { //letrasAceitas) {
		formarLetrasParaPreenchimento(preenchimento);

		letrasTudoPreenchido = getCopiaLetras();

		for(var i = 0; i < numeroDeLinhas; i++) {
			for(var j = 0; j < numeroDeColunas; j++) {
				if(letras[i][j] === letraVazia) {
					letrasTudoPreenchido[i][j] = letrasParaPreenchimento[i][j];
				}
			}
		}

		return this;
	};

	var formarLetrasParaPreenchimento = function(preenchimento) {
		var preenchimentoInterno = preenchimento === undefined ? {} : preenchimento;

		var letrasPossiveis = getLetrasPossiveis(preenchimento);

		if(preenchimentoInterno.previamenteDefinido === undefined) {
			for(var i = 0; i < numeroDeLinhas; i++) {
				letrasParaPreenchimento[i] = [];

				for(var j = 0; j < numeroDeColunas; j++)
					letrasParaPreenchimento[i][j] = letrasPossiveis[Math.floor(Math.random() * letrasPossiveis.length)];
			}
		}
		else {
			for(var i = 0; i < numeroDeLinhas; i++) {
				letrasParaPreenchimento[i] = [];

				if(preenchimentoInterno.previamenteDefinido[i] === undefined)
					preenchimentoInterno.previamenteDefinido[i] = [];

				for(var j = 0; j < numeroDeColunas; j++) {
					if(preenchimentoInterno.previamenteDefinido[i][j] === undefined)
						letrasParaPreenchimento[i][j] = letrasPossiveis[Math.floor(Math.random() * letrasPossiveis.length)];
					else
						letrasParaPreenchimento[i][j] = preenchimentoInterno.previamenteDefinido[i][j];
				}
			}
		}

		return letrasParaPreenchimento;
	};

	var getLetrasAceitas = function(preenchimento) {
		return (preenchimento.letrasAceitas === undefined || preenchimento.letrasAceitas.trim() === "") ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : preenchimento.letrasAceitas;
	};

	var getLetrasPossiveis = function(preenchimento) {
		if(preenchimento.mesmaLetraDasPalavras !== undefined && preenchimento.mesmaLetraDasPalavras === true)
			return getLetrasComMesmasLetrasDasPalavrasAdicionadas(preenchimento.letrasAceitas);
		else
			return getLetrasAceitas(preenchimento);
	};

	getLetrasComMesmasLetrasDasPalavrasAdicionadas = function(maisLetras) {
		var letrasParaAdicionar = "";

		for(var i = 0; i < palavras.length; i++) {
			for(var j = 0; j < palavras[i].length; j++) {
				letrasParaAdicionar += palavras[i][j];
			}
		}

		return letrasParaAdicionar + (maisLetras === undefined ? "" : maisLetras);
	};

	var tryAdicionarPalavraHorizontal = function(palavra, reverso, linhaInicial, colunaInicial) {
		for(var i = colunaInicial; i < colunaInicial + palavra.length; i++) {
			if(letras[linhaInicial][i] !== letraVazia)
				if(!podeCruzar)
					return false;
				else if(letras[linhaInicial][i].toUpperCase() !== (reverso ? palavra.split("").reverse().join("")[i - colunaInicial] : palavra[i - colunaInicial]).toUpperCase())
					return false;
		}

		return true;
	};

	var tryAdicionarPalavraVertical = function(palavra, reverso, linhaInicial, colunaInicial) {
		for(var i = linhaInicial; i < linhaInicial + palavra.length; i++) {
			if(letras[i][colunaInicial] !== letraVazia)
				if(!podeCruzar)
					return false;
				else if(letras[i][colunaInicial].toUpperCase() !== (reverso ? palavra.split("").reverse().join("")[i - linhaInicial] : palavra[i - linhaInicial]).toUpperCase())
					return false;
		}

		return true;
	};

	this.adicionarPalavraVertical = function(palavra, linhaInicial, colunaInicial, reverso) {
		if(palavra !== undefined) {
			var palavraInterno = palavra.trim();

			var linhaInicialInterno = (linhaInicial === undefined || linhaInicial > numeroDeLinhas - palavraInterno.length) ? (Math.floor(Math.random() * (numeroDeLinhas - palavraInterno.length + 1))) : linhaInicial;

			var colunaInicialInterno = (colunaInicial === undefined || colunaInicial >= numeroDeColunas) ? (Math.floor(Math.random() * numeroDeColunas)) : colunaInicial;

			var reversoInterno = reverso === undefined ? (Math.floor(Math.random() * (chancesParaReverso === undefined ? 2 : chancesParaReverso)) == 0 ? true : false) : reverso;

			if(palavraInterno.length <= letras.length) { // se o tamanho da palavraInterno for menor ou igual o tamanho da linha
				var linhaTentativa = linhaInicialInterno;
				var colunaTentativa = colunaInicialInterno;
				var tentativasFrustradasColunas = [];

				while(!tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					var tentativasFrustradasMesmaColuna = [];

					do {
						tentativasFrustradasMesmaColuna.push(linhaTentativa);

						if(tentativasFrustradasMesmaColuna.length == (numeroDeLinhas - palavraInterno.length + 1)) {
							break;
						}
						else {
							do { // linha não tentada ainda
								linhaTentativa = Math.floor(Math.random() * (numeroDeLinhas - palavraInterno.length + 1));
							} while(tentativasFrustradasMesmaColuna.indexOf(linhaTentativa) !== -1)
						}
					} while(!tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa));

					if(!tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
						tentativasFrustradasColunas.push(colunaTentativa);

						if(tentativasFrustradasColunas.length == numeroDeColunas) {
							break;
						}
						else {
							while(tentativasFrustradasColunas.indexOf(colunaTentativa) !== -1) {
								colunaTentativa = Math.floor(Math.random() * numeroDeColunas);
							}
						}
					}
				}

				if(tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					for(var i = linhaTentativa; i < linhaTentativa + palavraInterno.length; i++) {
						letras[i][colunaTentativa] = reversoInterno ? palavraInterno.split("").reverse().join("")[i - linhaTentativa] : palavraInterno[i - linhaTentativa];
					}

					palavras.push(palavraInterno);
				}
			}
		}

		return this;
	}

	this.adicionarPalavraHorizontal = function(palavra, linhaInicial, colunaInicial, reverso) {
		if(palavra !== undefined) {
			var palavraInterno = palavra.trim();

			var linhaInicialInterno = (linhaInicial === undefined || linhaInicial >= numeroDeLinhas) ? (Math.floor(Math.random() * numeroDeLinhas)) : linhaInicial;

			var colunaInicialInterno = (colunaInicial === undefined || colunaInicial > numeroDeColunas - palavraInterno.length) ? (Math.floor(Math.random() * (numeroDeColunas - palavraInterno.length + 1))) : colunaInicial;

			var reversoInterno = reverso === undefined ? (Math.floor(Math.random() * (chancesParaReverso === undefined ? 2 : chancesParaReverso)) == 0 ? true : false) : reverso;

			if(palavraInterno.length <= letras[linhaInicialInterno].length) { // se o tamanho da palavraInterno for menor ou igual o tamanho da linha
				var linhaTentativa = linhaInicialInterno;
				var colunaTentativa = colunaInicialInterno;
				var tentativasFrustradasLinhas = [];

				while(!tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					var tentativasFrustradasMesmaLinha = [];

					do {
						tentativasFrustradasMesmaLinha.push(colunaTentativa);

						if(tentativasFrustradasMesmaLinha.length == (numeroDeColunas - palavraInterno.length + 1)) {
							break;
						}
						else {
							do { // coluna não tentada ainda
								colunaTentativa = Math.floor(Math.random() * (numeroDeColunas - palavraInterno.length + 1));
							} while(tentativasFrustradasMesmaLinha.indexOf(colunaTentativa) !== -1)
						}
					} while(!tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa));

					if(!tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
						tentativasFrustradasLinhas.push(linhaTentativa);

						if(tentativasFrustradasLinhas.length == numeroDeLinhas) {
							break;
						}
						else {
							while(tentativasFrustradasLinhas.indexOf(linhaTentativa) !== -1) {
								linhaTentativa = Math.floor(Math.random() * numeroDeLinhas);
							}
						}
					}
				}

				if(tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					for(var i = colunaTentativa; i < colunaTentativa + palavraInterno.length; i++) {
						letras[linhaTentativa][i] = reversoInterno ? palavraInterno.split("").reverse().join("")[i - colunaTentativa] : palavraInterno[i - colunaTentativa];
					}

					palavras.push(palavraInterno);
				}
			}
		}

		return this;
	};

	this.adicionarPalavra = function(palavra, reverso, chancesParaHorizontal, chancesParaVertical) {
		if(palavra !== undefined) {
			var possibilidades = [];

			if(Math.floor((Math.random() * (chancesParaHorizontal === undefined ? 2 : chancesParaHorizontal))) === 0)
				possibilidades.push("horizontal");

			if(Math.floor((Math.random() * (chancesParaVertical === undefined ? 2 : chancesParaVertical))) === 0)
				possibilidades.push("vertical")

			var adicionarEscolhido = possibilidades[Math.floor(Math.random() * possibilidades.length)];

			if(adicionarEscolhido === "horizontal")
				return this.adicionarPalavraHorizontal(palavra, undefined, undefined, reverso);
			else if(adicionarEscolhido === "vertical")
				return this.adicionarPalavraVertical(palavra, undefined, undefined, reverso);

			return this.adicionarPalavraHorizontal(palavra, undefined, undefined, reverso);
		}

		return this;
	};

	this.adicionarPalavras = function(palavrasParaAdicionar) {
		for(var i = 0; i < palavrasParaAdicionar.length; i++)
			this.adicionarPalavra(palavrasParaAdicionar[i]);

		return this;
	};

	this.getLetra = function(linha, coluna) {
		return letras[linha][coluna];
	};

	this.getLetraComPreenchimento = function(linha, coluna) {
		return letrasTudoPreenchido[linha][coluna];
	};

	this.getPalavras = function() {
		return palavras;
	};
};

if(exports !== undefined)
	exports.cacaPalavras = cacaPalavras;<commit_msg>Palavras como array de objetos.<commit_after>var cacaPalavras = function(numeroDeLinhas, numeroDeColunas, podeCruzar, chancesParaReverso) {
	var palavras = [],
		letras = [],
		letrasParaPreenchimento = []
		letrasTudoPreenchido = [];

	var letraVazia = " ";

	for(var i = 0; i < numeroDeLinhas; i++) {
		letras[i] = [];

		for(var j = 0; j < numeroDeColunas; j++) {
			letras[i][j] = letraVazia;
		}
	}

	var getCopiaLetras = function() {
		var retorno = [];

		for(var i = 0; i < letras.length; i++)
			retorno.push(letras[i].slice());

		return retorno;
	};

	this.getShow = function getShow(getLetraCallback, preencherEspacoEmBranco, caracteresEsquerda, caracteresDireita, mostrarLinhas) {
		var output = "";

		for(var i = 0; i < numeroDeLinhas; i++) {
			output += mostrarLinhas ? ("000" + (i + 1)).slice(("000" + (i + 1)).length - 3, ("000" + (i + 1)).length) + ": " : "";

			for(var j = 0; j < numeroDeColunas; j++) {
				output +=
					((caracteresEsquerda === undefined) ? "" : caracteresEsquerda) +
					((getLetraCallback(i, j).trim() === "") ? (preencherEspacoEmBranco === undefined ? "+" : preencherEspacoEmBranco) : getLetraCallback(i, j)) +
					((caracteresDireita === undefined) ? "" : caracteresDireita);
			}

			output += "\r\n";
		}

		return output.toUpperCase();
	};

	this.getShowPalavras = function() {
		var output = "";

		for(var i = 0; i < palavras.length; i++) {
			output += palavras[i].palavra + (i < palavras.length - 1 ? "\n" : "");
		}

		return output;
	};

	this.preencherLetrasRestantes = function(preenchimento) { //letrasAceitas) {
		formarLetrasParaPreenchimento(preenchimento);

		letrasTudoPreenchido = getCopiaLetras();

		for(var i = 0; i < numeroDeLinhas; i++) {
			for(var j = 0; j < numeroDeColunas; j++) {
				if(letras[i][j] === letraVazia) {
					letrasTudoPreenchido[i][j] = letrasParaPreenchimento[i][j];
				}
			}
		}

		return this;
	};

	var formarLetrasParaPreenchimento = function(preenchimento) {
		var preenchimentoInterno = preenchimento === undefined ? {} : preenchimento;

		var letrasPossiveis = getLetrasPossiveis(preenchimento);

		if(preenchimentoInterno.previamenteDefinido === undefined) {
			for(var i = 0; i < numeroDeLinhas; i++) {
				letrasParaPreenchimento[i] = [];

				for(var j = 0; j < numeroDeColunas; j++)
					letrasParaPreenchimento[i][j] = letrasPossiveis[Math.floor(Math.random() * letrasPossiveis.length)];
			}
		}
		else {
			for(var i = 0; i < numeroDeLinhas; i++) {
				letrasParaPreenchimento[i] = [];

				if(preenchimentoInterno.previamenteDefinido[i] === undefined)
					preenchimentoInterno.previamenteDefinido[i] = [];

				for(var j = 0; j < numeroDeColunas; j++) {
					if(preenchimentoInterno.previamenteDefinido[i][j] === undefined)
						letrasParaPreenchimento[i][j] = letrasPossiveis[Math.floor(Math.random() * letrasPossiveis.length)];
					else
						letrasParaPreenchimento[i][j] = preenchimentoInterno.previamenteDefinido[i][j];
				}
			}
		}

		return letrasParaPreenchimento;
	};

	var getLetrasAceitas = function(preenchimento) {
		return (preenchimento.letrasAceitas === undefined || preenchimento.letrasAceitas.trim() === "") ? "ABCDEFGHIJKLMNOPQRSTUVWXYZ" : preenchimento.letrasAceitas;
	};

	var getLetrasPossiveis = function(preenchimento) {
		if(preenchimento.mesmaLetraDasPalavras !== undefined && preenchimento.mesmaLetraDasPalavras === true)
			return getLetrasComMesmasLetrasDasPalavrasAdicionadas(preenchimento.letrasAceitas);
		else
			return getLetrasAceitas(preenchimento);
	};

	getLetrasComMesmasLetrasDasPalavrasAdicionadas = function(maisLetras) {
		var letrasParaAdicionar = "";

		for(var i = 0; i < palavras.length; i++) {
			for(var j = 0; j < palavras[i].palavra.length; j++) {
				letrasParaAdicionar += palavras[i].palavra[j];
			}
		}

		return letrasParaAdicionar + (maisLetras === undefined ? "" : maisLetras);
	};

	var tryAdicionarPalavraHorizontal = function(palavra, reverso, linhaInicial, colunaInicial) {
		for(var i = colunaInicial; i < colunaInicial + palavra.length; i++) {
			if(letras[linhaInicial][i] !== letraVazia)
				if(!podeCruzar)
					return false;
				else if(letras[linhaInicial][i].toUpperCase() !== (reverso ? palavra.split("").reverse().join("")[i - colunaInicial] : palavra[i - colunaInicial]).toUpperCase())
					return false;
		}

		return true;
	};

	var tryAdicionarPalavraVertical = function(palavra, reverso, linhaInicial, colunaInicial) {
		for(var i = linhaInicial; i < linhaInicial + palavra.length; i++) {
			if(letras[i][colunaInicial] !== letraVazia)
				if(!podeCruzar)
					return false;
				else if(letras[i][colunaInicial].toUpperCase() !== (reverso ? palavra.split("").reverse().join("")[i - linhaInicial] : palavra[i - linhaInicial]).toUpperCase())
					return false;
		}

		return true;
	};

	this.adicionarPalavraVertical = function(palavra) {
		if(palavra !== undefined && palavra.palavra !== undefined) {
			var palavraInterno = palavra.palavra.trim();

			var linhaInicialInterno = (palavra.linhaInicial === undefined || palavra.linhaInicial > numeroDeLinhas - palavraInterno.length) ? (Math.floor(Math.random() * (numeroDeLinhas - palavraInterno.length + 1))) : linhaInicial;

			var colunaInicialInterno = (palavra.colunaInicial === undefined || palavra.colunaInicial >= numeroDeColunas) ? (Math.floor(Math.random() * numeroDeColunas)) : palavra.colunaInicial;

			var reversoInterno = palavra.reverso === undefined ? (Math.floor(Math.random() * (chancesParaReverso === undefined ? 2 : chancesParaReverso)) == 0 ? true : false) : palavra.reverso;

			if(palavraInterno.length <= letras.length) { // se o tamanho da palavraInterno for menor ou igual o tamanho da linha
				var linhaTentativa = linhaInicialInterno;
				var colunaTentativa = colunaInicialInterno;
				var tentativasFrustradasColunas = [];

				while(!tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					var tentativasFrustradasMesmaColuna = [];

					do {
						tentativasFrustradasMesmaColuna.push(linhaTentativa);

						if(tentativasFrustradasMesmaColuna.length == (numeroDeLinhas - palavraInterno.length + 1)) {
							break;
						}
						else {
							do { // linha não tentada ainda
								linhaTentativa = Math.floor(Math.random() * (numeroDeLinhas - palavraInterno.length + 1));
							} while(tentativasFrustradasMesmaColuna.indexOf(linhaTentativa) !== -1)
						}
					} while(!tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa));

					if(!tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
						tentativasFrustradasColunas.push(colunaTentativa);

						if(tentativasFrustradasColunas.length == numeroDeColunas) {
							break;
						}
						else {
							while(tentativasFrustradasColunas.indexOf(colunaTentativa) !== -1) {
								colunaTentativa = Math.floor(Math.random() * numeroDeColunas);
							}
						}
					}
				}

				if(tryAdicionarPalavraVertical(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					for(var i = linhaTentativa; i < linhaTentativa + palavraInterno.length; i++) {
						letras[i][colunaTentativa] = reversoInterno ? palavraInterno.split("").reverse().join("")[i - linhaTentativa] : palavraInterno[i - linhaTentativa];
					}

					palavras.push({ palavra: palavraInterno, linhaInicial: linhaTentativa, colunaInicial: colunaTentativa, reverso: reversoInterno });
				}
			}
		}

		return this;
	}

	this.adicionarPalavraHorizontal = function(palavra) {
		if(palavra !== undefined && palavra.palavra !== undefined) {
			var palavraInterno = palavra.palavra.trim();

			var linhaInicialInterno = (palavra.linhaInicial === undefined || palavra.linhaInicial >= numeroDeLinhas) ? (Math.floor(Math.random() * numeroDeLinhas)) : palavra.linhaInicial;

			var colunaInicialInterno = (palavra.colunaInicial === undefined || palavra.colunaInicial > numeroDeColunas - palavraInterno.length) ? (Math.floor(Math.random() * (numeroDeColunas - palavraInterno.length + 1))) : palavra.colunaInicial;

			var reversoInterno = palavra.reverso === undefined ? (Math.floor(Math.random() * (chancesParaReverso === undefined ? 2 : chancesParaReverso)) == 0 ? true : false) : palavra.reverso;

			if(palavraInterno.length <= letras[linhaInicialInterno].length) { // se o tamanho da palavraInterno for menor ou igual o tamanho da linha
				var linhaTentativa = linhaInicialInterno;
				var colunaTentativa = colunaInicialInterno;
				var tentativasFrustradasLinhas = [];

				while(!tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					var tentativasFrustradasMesmaLinha = [];

					do {
						tentativasFrustradasMesmaLinha.push(colunaTentativa);

						if(tentativasFrustradasMesmaLinha.length == (numeroDeColunas - palavraInterno.length + 1)) {
							break;
						}
						else {
							do { // coluna não tentada ainda
								colunaTentativa = Math.floor(Math.random() * (numeroDeColunas - palavraInterno.length + 1));
							} while(tentativasFrustradasMesmaLinha.indexOf(colunaTentativa) !== -1)
						}
					} while(!tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa));

					if(!tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
						tentativasFrustradasLinhas.push(linhaTentativa);

						if(tentativasFrustradasLinhas.length == numeroDeLinhas) {
							break;
						}
						else {
							while(tentativasFrustradasLinhas.indexOf(linhaTentativa) !== -1) {
								linhaTentativa = Math.floor(Math.random() * numeroDeLinhas);
							}
						}
					}
				}

				if(tryAdicionarPalavraHorizontal(palavraInterno, reversoInterno, linhaTentativa, colunaTentativa)) {
					for(var i = colunaTentativa; i < colunaTentativa + palavraInterno.length; i++) {
						letras[linhaTentativa][i] = reversoInterno ? palavraInterno.split("").reverse().join("")[i - colunaTentativa] : palavraInterno[i - colunaTentativa];
					}

					palavras.push({ palavra: palavraInterno, linhaInicial: linhaTentativa, colunaInicial: colunaTentativa, reverso: reversoInterno });
				}
			}
		}

		return this;
	};

	this.adicionarPalavra = function(palavra, chancesParaHorizontal, chancesParaVertical) {
		if(palavra !== undefined && palavra.palavra !== undefined) {
			var possibilidades = [];

			if(Math.floor((Math.random() * (chancesParaHorizontal === undefined ? 2 : chancesParaHorizontal))) === 0)
				possibilidades.push("horizontal");

			if(Math.floor((Math.random() * (chancesParaVertical === undefined ? 2 : chancesParaVertical))) === 0)
				possibilidades.push("vertical")

			var adicionarEscolhido = possibilidades[Math.floor(Math.random() * possibilidades.length)];

			if(adicionarEscolhido === "horizontal")
				return this.adicionarPalavraHorizontal(palavra);
			else if(adicionarEscolhido === "vertical")
				return this.adicionarPalavraVertical(palavra);

			return this.adicionarPalavraHorizontal(palavra);
		}

		return this;
	};

	this.adicionarPalavras = function(palavrasParaAdicionar) {
		for(var i = 0; i < palavrasParaAdicionar.length; i++)
			this.adicionarPalavra({ palavra: palavrasParaAdicionar[i] });

		return this;
	};

	this.getLetra = function(linha, coluna) {
		return letras[linha][coluna];
	};

	this.getLetraComPreenchimento = function(linha, coluna) {
		return letrasTudoPreenchido[linha][coluna];
	};

	this.getPalavras = function() {
		return palavras;
	};
};

if(exports !== undefined)
	exports.cacaPalavras = cacaPalavras;<|endoftext|>


<commit_before>if (!($ = window.jQuery)) { // typeof jQuery=='undefined' works too
	script = document.createElement( 'script' );
	script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js';
	script.onload=doWork;
	document.body.appendChild(script);
}
else {
    doWork();
}

function doWork() {
    alert('works!');
}
<commit_msg>testing parseint<commit_after>if (!($ = window.jQuery)) { // typeof jQuery=='undefined' works too
	script = document.createElement( 'script' );
	script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js';
	script.onload=doWork;
	document.body.appendChild(script);
}
else {
    doWork();
}

function doWork() {
    alert(parseInt('#1,119'));
}
<|endoftext|>


<commit_before>/*

*/
"use strict";

(function (jQuery) {
   var SourceArray = ["Lombardia", "Abruzzo", "Toscana", "Liguria"];
   var SourceAjaxArray = new Array();

   var delimeters = new Array();
   var backspace = new Array();
   var inputObj = null;
   var tagList = new Array();
   var tagLiID = new Array();
   var lastTagId = 0;
   var hiddenTagList = null;

   var tagManagerOptions = null;

   var queuedTag = "";

   if (typeof console === "undefined" || typeof console.log === "undefined") {
      console = {};
      console.log = function () { };
   }

   inputObj = this;

   jQuery.fn.trimTag = function (tag) {
      var txt = jQuery.trim(tag);

      var l = txt.length;
      var t = 0;

      //          console.log(
      //                "tag to trim : " + txt
      //              );
      //remove from end
      for (var i = l - 1; i >= 0; i--) {
         //            console.log(
         //                "char to evaluate : " + txt[i] + " (" + txt.charCodeAt(i) + ")"
         //              );
         if (-1 != jQuery.inArray(txt.charCodeAt(i), delimeters)) {
            //              console.log(
            //                "char to remove from end: " + txt[i]
            //              );
            t++;
         } else
            break;
      }
      txt = txt.substring(0, l - t);
      l = txt.length;
      t = 0;
      //remove from head
      for (var i = 0; i < l; i++) {
         //            console.log(
         //                "char to evaluate : " + txt[i] + " (" + txt.charCodeAt(i) + ")"
         //              );
         if (-1 != jQuery.inArray(txt.charCodeAt(i), delimeters)) {
            //              console.log(
            //                "char to remove from head: " + txt[i]
            //              );
            t++;
         } else
            break;
      }

      txt = txt.substring(t, l);
      //          console.log(
      //                "trimmed to : " + txt
      //              );

      return txt;
   };

   jQuery.fn.setupTypeahead = function (tag) {
      var obj = jQuery(this);

      if(!obj.typeahead)
         return;

      if (tagManagerOptions.typeaheadSource != null) {
         obj.typeahead();
         obj.data('active', true);
         obj.data('typeahead').source = tagManagerOptions.typeaheadSource;
         obj.data('active', false);
      } else if (tagManagerOptions.typeaheadAjaxSource != null) {
         obj.typeahead();
         jQuery.getJSON(tagManagerOptions.typeaheadAjaxSource, function (data) {
            if (data != undefined && data.tags != undefined) {
               SourceAjaxArray.length = 0;
               jQuery.each(data.tags, function (key, val) {
                  var a = 1;
                  //jQuery('#addexpenses select[name="who"]').append('<option value="' + val.who + '">' + val.name + '</option>');
                  SourceAjaxArray.push(val.tag);
                  //obj.attr("data-sources", SourceArray);
                  obj.data('active', true);
                  obj.data('typeahead').source = SourceAjaxArray;
                  obj.data('active', false);
                  //obj.attr("data-sources", SourceAjaxArray.join(", "));
               });
            }
         });
      }
   };

   jQuery.fn.refreshHiddenTagList = function (robj) {
      var obj;
      if (robj == null)
         obj = jQuery(this);
      else
         obj = robj;

      var tlis = obj.data("tlis");
      var lhiddenTagList = obj.data("lhiddenTagList");

      if(lhiddenTagList == undefined)
         return;

      jQuery(lhiddenTagList).val(tlis.join(","));
   };

   jQuery.fn.spliceTag = function (TagId,robj) {
      var obj;
      if (robj == null)
         return;
      else
         obj = robj;
      var tlis = obj.data("tlis");
      var tlid = obj.data("tlid");

      console.log(
              "TagIdToRemove: " + TagId
            );
      var p = jQuery.inArray(TagId, tlid)
      console.log(
              "position: " + p
            );
      if (-1 != p) {
         jQuery("#myTag_" + TagId).remove();
         tlis.splice(p, 1);
         tlid.splice(p, 1);
         obj.refreshHiddenTagList(obj);
         console.log(tlis);
      }

      if ( tagManagerOptions.maxTags > 0 && tlis.length < tagManagerOptions.maxTags ) {
         obj.show();
      }
   };

   jQuery.fn.popTag = function (robj) {
      var obj;
      if (robj == null)
         obj = jQuery(this);
      else
         obj = robj;

      var tlis = obj.data("tlis");
      var tlid = obj.data("tlid");

      if (tlid.length > 0) {
         var TagId = tlid.pop();
         tlis.pop();
         console.log(
              "TagIdToRemove: " + TagId
            );
         jQuery("#myTag_" + TagId).remove();
         jQuery(obj).refreshHiddenTagList();
         console.log(tlis);
      }
   };

   jQuery.fn.pushTag = function (tag, robj) {
      if (!tag || tag.length <= 0) {
         return;
      }
      if (tagManagerOptions.CapitalizeFirstLetter && tag.length > 1) {
         tag = tag.charAt(0).toUpperCase() + tag.slice(1).toLowerCase();
      }

      // call the validator (if any) and do not let the tag pass if invalid
      if (tagManagerOptions.validator !== undefined) {
        if ( tagManagerOptions.validator(tag) !== true ) return;
      }

      var obj;
      if (robj == null)
         obj = jQuery(this);
      else
         obj = robj;

      var tlis = obj.data("tlis");
      var tlid = obj.data("tlid");

      // dont accept new tags beyond the defined maximum
      if ( tagManagerOptions.maxTags > 0 && tlis.length >= tagManagerOptions.maxTags ) return;

      var alreadyInList = false;
      var p = jQuery.inArray(tag, tlis);
      if (-1 != p) {
         console.log(
                "tag:" + tag + " !!already in list!!"
              );
         alreadyInList = true;
      }

      if (alreadyInList) {
         var pTagId = tlid[p];
         jQuery("#myTag_" + pTagId).stop().animate({ backgroundColor: tagManagerOptions.blinkBGColor_1 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_2 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_1 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_2 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_1 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_2 }, 100);
      } else {
         var TagId = lastTagId++;
         tlis.push(tag);
         tlid.push(TagId);

         var html = '';
         html += '' + tag + '  x';
         console.log(
              "tagList: " + tlis
            );
         obj.before(html);
         jQuery("#myRemover_" + TagId).on("click", obj, function (e) {
			e.preventDefault();
            var TagIdToRemove = parseInt(jQuery(this).attr("TagIdToRemove"));

            e.data.spliceTag(TagIdToRemove,e.data);
//            var TagIdToRemove = parseInt(jQuery(this).attr("TagIdToRemove"));
//            jQuery(this).spliceTag(parseInt(jQuery(this).attr("TagIdToRemove")));
         });

         obj.refreshHiddenTagList(obj);

         if ( tagManagerOptions.maxTags > 0 && tlis.length >= tagManagerOptions.maxTags ) {
            obj.hide();
         }

      }
      obj.val("");

   };

   jQuery.fn.tagsManager = function (options) {
      tagManagerOptions = {
         prefilled: null,
         CapitalizeFirstLetter: true,
         preventSubmitOnEnter: true,
         typeahead: false,
         typeaheadAjaxSource: null,
         typeaheadSource: null,
         delimeters: [44, 188, 13],
         backspace: [8],
         maxTags: 0
      };
      jQuery.extend(tagManagerOptions, options);

      return this.each(function() {
         var obj = jQuery(this);

         //let's store some instance specific data directly into the DOM object
         var tlis = new Array();
         var tlid = new Array();
         obj.data("tlis", tlis); //list of string tags
         obj.data("tlid", tlid); //list of ID of the string tags

         var html = "";
         html += "<input name='hiddenTagList' type='hidden' value=''/>";
         obj.after(html);
         obj.data("lhiddenTagList",
            obj.siblings("input[name='hiddenTagList']")[0]
         );

         delimeters = tagManagerOptions.delimeters;
         backspace = tagManagerOptions.backspace;

         if (lastTagId > 0) {
            while (lastTagId > 0) {
               obj.popTag(obj);
               lastTagId--;
            }
         }

         if (tagManagerOptions.typeahead) {
            obj.setupTypeahead();
            //obj.typeahead({ source: SourceArray })
         }

         // disable submit on enter for this input field
         obj.on("focus", function (e) {
            if (jQuery(this).popover) {
               jQuery(this).popover("hide");
               //jQuery(this).popover = null;
            }
         });

         obj.on("keypress", function (e) {
            if (jQuery(this).popover) {
               jQuery(this).popover("hide");
               //jQuery(this).popover = null;
            }
            if (tagManagerOptions.preventSubmitOnEnter) {
               if (e.which == 13) {
                  e.cancelBubble = true;
                  e.returnValue = false;
                  e.stopPropagation();
                  e.preventDefault();
                  //e.keyCode = 9;
               }
            }
            console.log(
                     "keyup: " + e.keyCode
                   );
         });

         obj.on("keyup", obj, function (e) {
            if(e.which == 9){
               var ao = jQuery(".typeahead:visible");
               if (ao[0] != undefined) {
                  console.log('pressed tab with typeaheadIsVisible is visible');
               } else {
                  console.log('pressed tab with typeaheadIsVisible is NOT visible');
               }
            }
            var p = jQuery.inArray(e.which, delimeters);
            if (-1 != p) {
               //user just entered a valid delimeter
               var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
               user_input = jQuery(this).trimTag(user_input);
               e.data.pushTag(user_input,e.data);
               console.log(
                        "pushTag: keyup "
                      );
            }
   //         console.log(
   //                  "keyup: " + e.which
   //                );
         });

         obj.on("keydown", obj, function (e) {
            var p = jQuery.inArray(e.which, backspace);
            if (-1 != p) {
               //user just entered backspace or equivalent
               var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
               var i = user_input.length;
               if (i <= 0) {
                  console.log(
                     "backspace detected"
                   );
                  e.data.popTag();
               }
            }
         });

         obj.change(function (e) {
            e.cancelBubble = true;
            e.returnValue = false;
            e.stopPropagation();
            e.preventDefault();

            var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
            var is_explorer = navigator.userAgent.indexOf('MSIE') > -1;
            var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
            var is_safari = navigator.userAgent.indexOf("Safari") > -1;

            if(!is_chrome && !is_safari )
               jQuery(this).focus();

            console.log('Handler for .change() called, value selected:' + obj.val());
            var ao = jQuery(".typeahead:visible");
            if (ao[0] != undefined){
               console.log('change: typeaheadIsVisible is visible');
               //when the user click with the mouse on the typeahead li element we get the change event fired twice, once when the input field loose focus and later with the input field value is replaced with li value
               var user_input = jQuery(".typeahead .active").attr("data-value");
               user_input = jQuery(this).trimTag(user_input);
               if( queuedTag == obj.val() && queuedTag == user_input ){
                  queuedTag = "";
                  obj.val(queuedTag);
               }else{
                  jQuery(this).pushTag(user_input);
                  queuedTag = user_input;
                  console.log('Handler for .change() called, typeahead value pushed:' + queuedTag);
               }
            } else {
               console.log('change: typeaheadIsVisible is NOT visible');
               var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
               user_input = jQuery(this).trimTag(user_input);
               jQuery(this).pushTag(user_input);
               console.log(
                        "pushTag: change "
                      );
            }

         });

         if (1 == 1 || !tagManagerOptions.typeahead) {
            obj.on("blur", function (e) {
               //lost focus
               e.cancelBubble = true;
               e.returnValue = false;
               e.stopPropagation();
               e.preventDefault();

               var push = true;
               if (tagManagerOptions.typeahead) {
                  var ao = jQuery(".typeahead:visible");
                  if (ao[0] != undefined) {
                     console.log('blur: typeaheadIsVisible is visible');
                     push = false;
                  } else {
                     console.log('blur: typeaheadIsVisible is NOT visible');
                     push = true;
                  }
               }

               if (push) {
                  console.log('lost focus');
                  var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
                  user_input = jQuery(this).trimTag(user_input);
                  jQuery(this).pushTag(user_input);
                  console.log(
                           "pushTag: blur"
                         );
               }
            });
         }

         if (tagManagerOptions.prefilled != null) {
            if (typeof (tagManagerOptions.prefilled) == "object") {
               var pta = tagManagerOptions.prefilled;
               jQuery.each(pta, function (key, val) {
                  var a = 1;
                  obj.pushTag(val, obj);
               });
            } else if (typeof (tagManagerOptions.prefilled) == "string") {
               var pta = tagManagerOptions.prefilled.split(',');

               jQuery.each(pta, function (key, val) {
                  var a = 1;
                  obj.pushTag(val, obj);
               });

            }
         }
      });

   }
})(jQuery);
<commit_msg>Personalized name for hidden tags list field<commit_after>/*

*/
"use strict";

(function (jQuery) {
   var SourceArray = ["Lombardia", "Abruzzo", "Toscana", "Liguria"];
   var SourceAjaxArray = new Array();

   var delimeters = new Array();
   var backspace = new Array();
   var inputObj = null;
   var tagList = new Array();
   var tagLiID = new Array();
   var lastTagId = 0;
   var hiddenTagList = null;

   var tagManagerOptions = null;

   var queuedTag = "";

   if (typeof console === "undefined" || typeof console.log === "undefined") {
      console = {};
      console.log = function () { };
   }

   inputObj = this;

   jQuery.fn.trimTag = function (tag) {
      var txt = jQuery.trim(tag);

      var l = txt.length;
      var t = 0;

      //          console.log(
      //                "tag to trim : " + txt
      //              );
      //remove from end
      for (var i = l - 1; i >= 0; i--) {
         //            console.log(
         //                "char to evaluate : " + txt[i] + " (" + txt.charCodeAt(i) + ")"
         //              );
         if (-1 != jQuery.inArray(txt.charCodeAt(i), delimeters)) {
            //              console.log(
            //                "char to remove from end: " + txt[i]
            //              );
            t++;
         } else
            break;
      }
      txt = txt.substring(0, l - t);
      l = txt.length;
      t = 0;
      //remove from head
      for (var i = 0; i < l; i++) {
         //            console.log(
         //                "char to evaluate : " + txt[i] + " (" + txt.charCodeAt(i) + ")"
         //              );
         if (-1 != jQuery.inArray(txt.charCodeAt(i), delimeters)) {
            //              console.log(
            //                "char to remove from head: " + txt[i]
            //              );
            t++;
         } else
            break;
      }

      txt = txt.substring(t, l);
      //          console.log(
      //                "trimmed to : " + txt
      //              );

      return txt;
   };

   jQuery.fn.setupTypeahead = function (tag) {
      var obj = jQuery(this);

      if(!obj.typeahead)
         return;

      if (tagManagerOptions.typeaheadSource != null) {
         obj.typeahead();
         obj.data('active', true);
         obj.data('typeahead').source = tagManagerOptions.typeaheadSource;
         obj.data('active', false);
      } else if (tagManagerOptions.typeaheadAjaxSource != null) {
         obj.typeahead();
         jQuery.getJSON(tagManagerOptions.typeaheadAjaxSource, function (data) {
            if (data != undefined && data.tags != undefined) {
               SourceAjaxArray.length = 0;
               jQuery.each(data.tags, function (key, val) {
                  var a = 1;
                  //jQuery('#addexpenses select[name="who"]').append('<option value="' + val.who + '">' + val.name + '</option>');
                  SourceAjaxArray.push(val.tag);
                  //obj.attr("data-sources", SourceArray);
                  obj.data('active', true);
                  obj.data('typeahead').source = SourceAjaxArray;
                  obj.data('active', false);
                  //obj.attr("data-sources", SourceAjaxArray.join(", "));
               });
            }
         });
      }
   };

   jQuery.fn.refreshHiddenTagList = function (robj) {
      var obj;
      if (robj == null)
         obj = jQuery(this);
      else
         obj = robj;

      var tlis = obj.data("tlis");
      var lhiddenTagList = obj.data("lhiddenTagList");

      if(lhiddenTagList == undefined)
         return;

      jQuery(lhiddenTagList).val(tlis.join(","));
   };

   jQuery.fn.spliceTag = function (TagId,robj) {
      var obj;
      if (robj == null)
         return;
      else
         obj = robj;
      var tlis = obj.data("tlis");
      var tlid = obj.data("tlid");

      console.log(
              "TagIdToRemove: " + TagId
            );
      var p = jQuery.inArray(TagId, tlid)
      console.log(
              "position: " + p
            );
      if (-1 != p) {
         jQuery("#myTag_" + TagId).remove();
         tlis.splice(p, 1);
         tlid.splice(p, 1);
         obj.refreshHiddenTagList(obj);
         console.log(tlis);
      }

      if ( tagManagerOptions.maxTags > 0 && tlis.length < tagManagerOptions.maxTags ) {
         obj.show();
      }
   };

   jQuery.fn.popTag = function (robj) {
      var obj;
      if (robj == null)
         obj = jQuery(this);
      else
         obj = robj;

      var tlis = obj.data("tlis");
      var tlid = obj.data("tlid");

      if (tlid.length > 0) {
         var TagId = tlid.pop();
         tlis.pop();
         console.log(
              "TagIdToRemove: " + TagId
            );
         jQuery("#myTag_" + TagId).remove();
         jQuery(obj).refreshHiddenTagList();
         console.log(tlis);
      }
   };

   jQuery.fn.pushTag = function (tag, robj) {
      if (!tag || tag.length <= 0) {
         return;
      }
      if (tagManagerOptions.CapitalizeFirstLetter && tag.length > 1) {
         tag = tag.charAt(0).toUpperCase() + tag.slice(1).toLowerCase();
      }

      // call the validator (if any) and do not let the tag pass if invalid
      if (tagManagerOptions.validator !== undefined) {
        if ( tagManagerOptions.validator(tag) !== true ) return;
      }

      var obj;
      if (robj == null)
         obj = jQuery(this);
      else
         obj = robj;

      var tlis = obj.data("tlis");
      var tlid = obj.data("tlid");

      // dont accept new tags beyond the defined maximum
      if ( tagManagerOptions.maxTags > 0 && tlis.length >= tagManagerOptions.maxTags ) return;

      var alreadyInList = false;
      var p = jQuery.inArray(tag, tlis);
      if (-1 != p) {
         console.log(
                "tag:" + tag + " !!already in list!!"
              );
         alreadyInList = true;
      }

      if (alreadyInList) {
         var pTagId = tlid[p];
         jQuery("#myTag_" + pTagId).stop().animate({ backgroundColor: tagManagerOptions.blinkBGColor_1 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_2 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_1 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_2 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_1 }, 100).animate({ backgroundColor: tagManagerOptions.blinkBGColor_2 }, 100);
      } else {
         var TagId = lastTagId++;
         tlis.push(tag);
         tlid.push(TagId);

         var html = '';
         html += '' + tag + '  x';
         console.log(
              "tagList: " + tlis
            );
         obj.before(html);
         jQuery("#myRemover_" + TagId).on("click", obj, function (e) {
			e.preventDefault();
            var TagIdToRemove = parseInt(jQuery(this).attr("TagIdToRemove"));

            e.data.spliceTag(TagIdToRemove,e.data);
//            var TagIdToRemove = parseInt(jQuery(this).attr("TagIdToRemove"));
//            jQuery(this).spliceTag(parseInt(jQuery(this).attr("TagIdToRemove")));
         });

         obj.refreshHiddenTagList(obj);

         if ( tagManagerOptions.maxTags > 0 && tlis.length >= tagManagerOptions.maxTags ) {
            obj.hide();
         }

      }
      obj.val("");

   };

   jQuery.fn.tagsManager = function (options) {
      tagManagerOptions = {
         prefilled: null,
         CapitalizeFirstLetter: true,
         preventSubmitOnEnter: true,
         typeahead: false,
         typeaheadAjaxSource: null,
         typeaheadSource: null,
         delimeters: [44, 188, 13],
         backspace: [8],
         maxTags: 0,
         hiddenTagListName: 'hiddenTagList'
      };
      jQuery.extend(tagManagerOptions, options);

      return this.each(function() {
         var obj = jQuery(this);

         //let's store some instance specific data directly into the DOM object
         var tlis = new Array();
         var tlid = new Array();
         obj.data("tlis", tlis); //list of string tags
         obj.data("tlid", tlid); //list of ID of the string tags

         var html = "";
         html += "<input name='" + tagManagerOptions.hiddenTagListName + "' type='hidden' value=''/>";
         obj.after(html);
         obj.data("lhiddenTagList",
            obj.siblings("input[name='" + tagManagerOptions.hiddenTagListName + "']")[0]
         );

         delimeters = tagManagerOptions.delimeters;
         backspace = tagManagerOptions.backspace;

         if (lastTagId > 0) {
            while (lastTagId > 0) {
               obj.popTag(obj);
               lastTagId--;
            }
         }

         if (tagManagerOptions.typeahead) {
            obj.setupTypeahead();
            //obj.typeahead({ source: SourceArray })
         }

         // disable submit on enter for this input field
         obj.on("focus", function (e) {
            if (jQuery(this).popover) {
               jQuery(this).popover("hide");
               //jQuery(this).popover = null;
            }
         });

         obj.on("keypress", function (e) {
            if (jQuery(this).popover) {
               jQuery(this).popover("hide");
               //jQuery(this).popover = null;
            }
            if (tagManagerOptions.preventSubmitOnEnter) {
               if (e.which == 13) {
                  e.cancelBubble = true;
                  e.returnValue = false;
                  e.stopPropagation();
                  e.preventDefault();
                  //e.keyCode = 9;
               }
            }
            console.log(
                     "keyup: " + e.keyCode
                   );
         });

         obj.on("keyup", obj, function (e) {
            if(e.which == 9){
               var ao = jQuery(".typeahead:visible");
               if (ao[0] != undefined) {
                  console.log('pressed tab with typeaheadIsVisible is visible');
               } else {
                  console.log('pressed tab with typeaheadIsVisible is NOT visible');
               }
            }
            var p = jQuery.inArray(e.which, delimeters);
            if (-1 != p) {
               //user just entered a valid delimeter
               var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
               user_input = jQuery(this).trimTag(user_input);
               e.data.pushTag(user_input,e.data);
               console.log(
                        "pushTag: keyup "
                      );
            }
   //         console.log(
   //                  "keyup: " + e.which
   //                );
         });

         obj.on("keydown", obj, function (e) {
            var p = jQuery.inArray(e.which, backspace);
            if (-1 != p) {
               //user just entered backspace or equivalent
               var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
               var i = user_input.length;
               if (i <= 0) {
                  console.log(
                     "backspace detected"
                   );
                  e.data.popTag();
               }
            }
         });

         obj.change(function (e) {
            e.cancelBubble = true;
            e.returnValue = false;
            e.stopPropagation();
            e.preventDefault();

            var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
            var is_explorer = navigator.userAgent.indexOf('MSIE') > -1;
            var is_firefox = navigator.userAgent.indexOf('Firefox') > -1;
            var is_safari = navigator.userAgent.indexOf("Safari") > -1;

            if(!is_chrome && !is_safari )
               jQuery(this).focus();

            console.log('Handler for .change() called, value selected:' + obj.val());
            var ao = jQuery(".typeahead:visible");
            if (ao[0] != undefined){
               console.log('change: typeaheadIsVisible is visible');
               //when the user click with the mouse on the typeahead li element we get the change event fired twice, once when the input field loose focus and later with the input field value is replaced with li value
               var user_input = jQuery(".typeahead .active").attr("data-value");
               user_input = jQuery(this).trimTag(user_input);
               if( queuedTag == obj.val() && queuedTag == user_input ){
                  queuedTag = "";
                  obj.val(queuedTag);
               }else{
                  jQuery(this).pushTag(user_input);
                  queuedTag = user_input;
                  console.log('Handler for .change() called, typeahead value pushed:' + queuedTag);
               }
            } else {
               console.log('change: typeaheadIsVisible is NOT visible');
               var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
               user_input = jQuery(this).trimTag(user_input);
               jQuery(this).pushTag(user_input);
               console.log(
                        "pushTag: change "
                      );
            }

         });

         if (1 == 1 || !tagManagerOptions.typeahead) {
            obj.on("blur", function (e) {
               //lost focus
               e.cancelBubble = true;
               e.returnValue = false;
               e.stopPropagation();
               e.preventDefault();

               var push = true;
               if (tagManagerOptions.typeahead) {
                  var ao = jQuery(".typeahead:visible");
                  if (ao[0] != undefined) {
                     console.log('blur: typeaheadIsVisible is visible');
                     push = false;
                  } else {
                     console.log('blur: typeaheadIsVisible is NOT visible');
                     push = true;
                  }
               }

               if (push) {
                  console.log('lost focus');
                  var user_input = jQuery(this).val(); //user_input = jQuery().inArray(delimeters[p]);
                  user_input = jQuery(this).trimTag(user_input);
                  jQuery(this).pushTag(user_input);
                  console.log(
                           "pushTag: blur"
                         );
               }
            });
         }

         if (tagManagerOptions.prefilled != null) {
            if (typeof (tagManagerOptions.prefilled) == "object") {
               var pta = tagManagerOptions.prefilled;
               jQuery.each(pta, function (key, val) {
                  var a = 1;
                  obj.pushTag(val, obj);
               });
            } else if (typeof (tagManagerOptions.prefilled) == "string") {
               var pta = tagManagerOptions.prefilled.split(',');

               jQuery.each(pta, function (key, val) {
                  var a = 1;
                  obj.pushTag(val, obj);
               });

            }
         }
      });

   }
})(jQuery);
<|endoftext|>


<commit_before>/**
 * @fileoverview Description of file, its uses and information
 * about its dependencies.
 */

'use strict';

var extensions;
var modules;
var tmpl;
var urlparser = require('./../modules/urlparser');
var urlVars = urlparser.urlVars;
var backboneEvents;

const semver = require('semver');
require("bootstrap");

module.exports = {

    /**
     *
     * @param o
     * @returns {exports}
     */
    set: function (o) {
        modules = o;
        backboneEvents = o.backboneEvents;
        return this;
    },

    /**
     *
     */
    init: function () {
        var me = this, configFile, stop = false;

        var loadConfig = function () {
            $.getJSON("/api/config/" + urlparser.db + "/" + configFile, function (data) {
                window.vidiConfig.brandName = data.brandName ? data.brandName : window.vidiConfig.brandName;
                window.vidiConfig.baseLayers = data.baseLayers ? data.baseLayers : window.vidiConfig.baseLayers;
                window.vidiConfig.enabledExtensions = data.enabledExtensions ? data.enabledExtensions : window.vidiConfig.enabledExtensions;
                window.vidiConfig.searchConfig = data.searchConfig ? data.searchConfig : window.vidiConfig.searchConfig;
                window.vidiConfig.aboutBox = data.aboutBox ? data.aboutBox : window.vidiConfig.aboutBox;
                window.vidiConfig.enabledSearch = data.enabledSearch ? data.enabledSearch : window.vidiConfig.enabledSearch;
                window.vidiConfig.schemata = data.schemata ? data.schemata : window.vidiConfig.schemata;
                window.vidiConfig.template = data.template ? data.template : window.vidiConfig.template;
                window.vidiConfig.enabledPrints = data.enabledPrints ? data.enabledPrints : window.vidiConfig.enabledPrints;
                window.vidiConfig.activateMainTab = data.activateMainTab ? data.activateMainTab : window.vidiConfig.activateMainTab;
                window.vidiConfig.extensionConfig = data.extensionConfig ? data.extensionConfig : window.vidiConfig.extensionConfig;
                window.vidiConfig.singleTiled = data.singleTiled ? data.singleTiled : window.vidiConfig.singleTiled;
                window.vidiConfig.doNotCloseLoadScreen = data.doNotCloseLoadScreen ? data.doNotCloseLoadScreen : window.vidiConfig.doNotCloseLoadScreen;
            }).fail(function () {
                console.log("Could not load: " + configFile);

                if (stop) {
                    me.getVersion();
                    return;
                }

                if (window.vidiConfig.defaultConfig) {
                    configFile = window.vidiConfig.defaultConfig;
                    stop = true;
                    loadConfig();
                }
            }).done(function () {
                me.getVersion();
            });
        };

        if (urlVars.config) {
            configFile = urlVars.config;
        } else if (window.vidiConfig.autoLoadingConfig) {
            configFile = urlparser.db + ".json";
        } else if (window.vidiConfig.defaultConfig) {
            configFile = window.vidiConfig.defaultConfig;
        }

        if (configFile) {
            loadConfig();
        } else {
            me.getVersion();
        }
    },

    getVersion: function () {
        var me = this;
        $.getJSON(`/app/${urlparser.db}/public/version.json`, function (data) {
            window.vidiConfig.appVersion = data.version;
            window.vidiConfig.appExtensionsBuild = '0';
            if (`extensionsBuild` in data) {
                window.vidiConfig.appExtensionsBuild = data.extensionsBuild;
            }
        }).fail(function () {
            console.error(`Unable to detect the current application version`);
        }).always(function () {
            me.render();
        });
    },

    /**
     *
     */
    render: function () {
        var me = this;

        // Render template and set some styling
        // ====================================

        if (typeof window.vidiConfig.template === "undefined") {
            tmpl = "default.tmpl";
        } else {
            tmpl = window.vidiConfig.template;
        }

        // Check if template is set in URL vars
        // ====================================

        if (typeof urlVars.tmpl !== "undefined") {
            var par = urlVars.tmpl.split("#");
            if (par.length > 1) {
                par.pop();
            }
            tmpl = par.join();
        }

        // If px and py is provided for print templates,
        // add the values to the dict before rendering
        // =============================================

        if (urlVars.px && urlVars.py) {
            gc2i18n.dict.printWidth = urlVars.px + "px";
            gc2i18n.dict.printHeight = urlVars.py + "px";
            gc2i18n.dict.printDataTime = decodeURIComponent(urlVars.td); // TODO typo
            gc2i18n.dict.printDateTime = decodeURIComponent(urlVars.td);
            gc2i18n.dict.printDate = decodeURIComponent(urlVars.d);
            window.vidiTimeout = 1000;
        } else {
            window.vidiTimeout = 0;
        }

        if (urlVars.l) {
            gc2i18n.dict._showLegend = urlVars.l;
        }
        gc2i18n.dict._showHeader = urlVars.h || "inline";
        gc2i18n.dict.brandName = window.vidiConfig.brandName;
        gc2i18n.dict.aboutBox = window.vidiConfig.aboutBox;

        // Render the page
        // ===============

        if (typeof Templates[tmpl] !== "undefined") {
            $("#main-container").html(Templates[tmpl].render(gc2i18n.dict));
            console.info("Using pre-processed template: " + tmpl);
            me.startApp();
        } else {
            $.get("/api/template/" + urlparser.db + "/" + tmpl, function (template) {
                var rendered = Mustache.render(template, gc2i18n.dict);
                $("#main-container").html(rendered);
                console.info("Loaded external template: " + tmpl);
                me.startApp();
            }).fail(function () {
                alert("Could not load template: " + tmpl);
            })
        }
    },

    /**
     *
     */
    startApp: function () {

        // Load style sheet
        //===================

        $('<link/>').attr({
            rel: 'stylesheet',
            type: 'text/css',
            href: '/css/styles.css'
        }).appendTo('head');

        // Add the tooltip div
        // ===================

        $("body").append('

');

        // Detect the database and schema
        let splitLocation = window.location.pathname.split(`/`);
        if (splitLocation.length === 4 || splitLocation.length === 5) {
            let database = splitLocation[2];
            let schema = splitLocation[3];
            if (!database || database.length === 0 || !schema || schema.length === 0) {
                console.warn(`Unable to detect current database and schema`);
            } else {
                window.vidiConfig.appDatabase = database;
                window.vidiConfig.appSchema = schema;
            }
        } else {
            console.warn(`Unable to detect current database and schema`);
        }

        // Init the modules
        // ================

        modules.cloud.init();
        modules.state.setExtent();

        // Calling mandatory init method
        [`backboneEvents`, `socketId`, `bindEvent`, `baseLayer`, `infoClick`,
            `advancedInfo`, `draw`, `measurements`, `stateSnapshots`, `print`, `layerTree`].map(name => {
            modules[name].init();
        });

        /**
         * Fetch meta > initialize settings > create layer tree >
         * initialize state > load layers > initialize extensions > finish
         */
        modules.meta.init().then(() => {
            return modules.setting.init();
        }, (error) => {
            console.log(error); // Stacktrace
            alert("Vidi is loaded without schema. Can't set extent or add layers");
            backboneEvents.get().trigger("ready:meta");
        }).then(() => {
            return modules.layerTree.create();
        }).finally(() => {
            modules.state.init().then(() => {

                try {

                // Require search module
                // =====================

                // Hack to compile Glob files. Don´t call this function!
                function ಠ_ಠ() {
                    require('./search/*.js', {glob: true});
                }

                if (typeof vidiConfig.searchModules !== "undefined") {
                    $.each(vidiConfig.searchModules, function (i, v) {
                        modules.search[v] = require('./search/' + v + '.js');
                        modules.search[v].set(modules);
                    });
                    modules.search[window.vidiConfig.enabledSearch].init();
                }

                // Require extensions modules
                // ==========================

                //Hack to compile Glob files. Don´t call this function!
                function ಠ_ಠ() {
                    require('./../../extensions/*/browser/*.js', {glob: true});
                    require('./../../extensions/*/browser/*/*.js', {glob: true});
                }

                if (typeof vidiConfig.extensions !== "undefined" && typeof vidiConfig.extensions.browser !== "undefined") {
                    $.each(vidiConfig.extensions.browser, function (i, v) {
                        modules.extensions[Object.keys(v)[0]] = {};
                        $.each(v[Object.keys(v)[0]], function (n, m) {
                            modules.extensions[Object.keys(v)[0]][m] = require('./../../extensions/' + Object.keys(v)[0] + '/browser/' + m + ".js");
                            modules.extensions[Object.keys(v)[0]][m].set(modules);
                        })
                    });

                    if (typeof window.vidiConfig.enabledExtensions === "object") {
                        let enabledExtensionsCopy = JSON.parse(JSON.stringify(window.vidiConfig.enabledExtensions));
                        $.each(vidiConfig.extensions.browser, function (i, v) {
                            $.each(v[Object.keys(v)[0]], function (n, m) {
                                let enabledExtensionIndex = enabledExtensionsCopy.indexOf(Object.keys(v)[0]);
                                if (enabledExtensionIndex > -1) {
                                    modules.extensions[Object.keys(v)[0]][m].init();
                                    enabledExtensionsCopy.splice(enabledExtensionIndex, 1);
                                }
                            })
                        });

                        if (enabledExtensionsCopy.length > 0) {
                            console.warn('Following extensions need to be enabled, but they were not initially compiled: ' + JSON.stringify(enabledExtensionsCopy));
                        }
                    }
                }

                // Init some GUI stuff after modules are loaded
                // ============================================
                $("[data-toggle=tooltip]").tooltip();

                $.material.init();
                touchScroll(".tab-pane");
                touchScroll("#info-modal-body-wrapper");
                $("#loadscreentext").html(__("Loading data"));
                if (window.vidiConfig.activateMainTab) {
                    setTimeout(function () {
                        $('#main-tabs a[href="#' + window.vidiConfig.activateMainTab + '-content"]').tab('show');
                    }, 200);
                }

                $(window).resize(_.debounce(function () {
                    $("#myNavmenu").offcanvas('hide');
                    setTimeout(function () {
                        modules.cloud.get().map.invalidateSize();
                    }, 100);
                }, 0));

                } catch (e) {
                    console.error("Could not perform application initialization", e.message);
                }
            });
        });

        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/service-worker.bundle.js').then((registration) => {
                console.log('Service worker registration succeeded');
            }).catch(error => {
                console.error(`Unable to register the service worker, please load the application over HTTPS in order to use its full functionality`);
            });
        } else {
            console.warn(`Service workers are not supported in this browser, some features may be unavailable`);
        }

        if (window.localforage) {
            localforage.getItem('appVersion').then(versionValue => {
                localforage.getItem('appExtensionsBuild').then(extensionsBuildValue => {
                    if (versionValue === null) {
                        localforage.setItem('appVersion', window.vidiConfig.appVersion).then(() => {
                            localforage.setItem('appExtensionsBuild', window.vidiConfig.appExtensionsBuild).then(() => {
                                console.log(`Versioning: setting new application version (${window.vidiConfig.appVersion}, ${window.vidiConfig.appExtensionsBuild})`);
                            });
                        }).catch(error => {
                            throw new Error(`Unable to store current application version`);
                        });
                    } else {
                        // If two versions are correctly detected
                        if (semver.valid(window.vidiConfig.appVersion) !== null && semver.valid(versionValue) !== null) {
                            if (semver.gt(window.vidiConfig.appVersion, versionValue) ||
                                (window.vidiConfig.appVersion === versionValue && window.vidiConfig.appExtensionsBuild !== extensionsBuildValue)) {
                                if (confirm(`Update application to the newest version (current: ${versionValue}, extensions: ${extensionsBuildValue}, latest: ${window.vidiConfig.appVersion}, extensions: ${window.vidiConfig.appExtensionsBuild})?`)) {
                                    let unregisteringRequests = [];

                                    // Unregister service worker
                                    navigator.serviceWorker.getRegistrations().then((registrations) => {
                                        for(let registration of registrations) {
                                            console.log(`Versioning: unregistering service worker`, registration);
                                            unregisteringRequests.push(registration.unregister());
                                            registration.unregister();
                                        }
                                    });

                                    Promise.all(unregisteringRequests).then((values) => {
                                        // Clear caches
                                        caches.keys().then(function(names) {
                                            for (let name of names) {
                                                console.log(`Versioning: clearing cache`, name);
                                                caches.delete(name);
                                            }
                                        });

                                        // Remove current app version
                                        localforage.removeItem('appVersion').then(() => {
                                            location.reload();
                                        });
                                    });
                                }
                            } else {
                                console.log('Versioning: new application version is not available');
                            }
                        } else if (typeof value === "undefined" || semver.valid(value) === null) {
                            console.warn(`Seems like current application version is invalid, resetting it`);
                            localforage.setItem('appVersion', '1.0.0').then(() => {}).catch(error => {
                                localforage.setItem('appExtensionsBuild', '0').then(() => {}).catch(error => {
                                    throw new Error(`Unable to store current application version`);
                                });
                            });
                        }
                    }
                });
            });
        } else {
            throw new Error(`localforage is not available`);
        }
    }
};<commit_msg>Restoring module initialization mechanism (for modules that have not only the index)<commit_after>/**
 * @fileoverview Description of file, its uses and information
 * about its dependencies.
 */

'use strict';

var extensions;
var modules;
var tmpl;
var urlparser = require('./../modules/urlparser');
var urlVars = urlparser.urlVars;
var backboneEvents;

const semver = require('semver');
require("bootstrap");

module.exports = {

    /**
     *
     * @param o
     * @returns {exports}
     */
    set: function (o) {
        modules = o;
        backboneEvents = o.backboneEvents;
        return this;
    },

    /**
     *
     */
    init: function () {
        var me = this, configFile, stop = false;

        var loadConfig = function () {
            $.getJSON("/api/config/" + urlparser.db + "/" + configFile, function (data) {
                window.vidiConfig.brandName = data.brandName ? data.brandName : window.vidiConfig.brandName;
                window.vidiConfig.baseLayers = data.baseLayers ? data.baseLayers : window.vidiConfig.baseLayers;
                window.vidiConfig.enabledExtensions = data.enabledExtensions ? data.enabledExtensions : window.vidiConfig.enabledExtensions;
                window.vidiConfig.searchConfig = data.searchConfig ? data.searchConfig : window.vidiConfig.searchConfig;
                window.vidiConfig.aboutBox = data.aboutBox ? data.aboutBox : window.vidiConfig.aboutBox;
                window.vidiConfig.enabledSearch = data.enabledSearch ? data.enabledSearch : window.vidiConfig.enabledSearch;
                window.vidiConfig.schemata = data.schemata ? data.schemata : window.vidiConfig.schemata;
                window.vidiConfig.template = data.template ? data.template : window.vidiConfig.template;
                window.vidiConfig.enabledPrints = data.enabledPrints ? data.enabledPrints : window.vidiConfig.enabledPrints;
                window.vidiConfig.activateMainTab = data.activateMainTab ? data.activateMainTab : window.vidiConfig.activateMainTab;
                window.vidiConfig.extensionConfig = data.extensionConfig ? data.extensionConfig : window.vidiConfig.extensionConfig;
                window.vidiConfig.singleTiled = data.singleTiled ? data.singleTiled : window.vidiConfig.singleTiled;
                window.vidiConfig.doNotCloseLoadScreen = data.doNotCloseLoadScreen ? data.doNotCloseLoadScreen : window.vidiConfig.doNotCloseLoadScreen;
            }).fail(function () {
                console.log("Could not load: " + configFile);

                if (stop) {
                    me.getVersion();
                    return;
                }

                if (window.vidiConfig.defaultConfig) {
                    configFile = window.vidiConfig.defaultConfig;
                    stop = true;
                    loadConfig();
                }
            }).done(function () {
                me.getVersion();
            });
        };

        if (urlVars.config) {
            configFile = urlVars.config;
        } else if (window.vidiConfig.autoLoadingConfig) {
            configFile = urlparser.db + ".json";
        } else if (window.vidiConfig.defaultConfig) {
            configFile = window.vidiConfig.defaultConfig;
        }

        if (configFile) {
            loadConfig();
        } else {
            me.getVersion();
        }
    },

    getVersion: function () {
        var me = this;
        $.getJSON(`/app/${urlparser.db}/public/version.json`, function (data) {
            window.vidiConfig.appVersion = data.version;
            window.vidiConfig.appExtensionsBuild = '0';
            if (`extensionsBuild` in data) {
                window.vidiConfig.appExtensionsBuild = data.extensionsBuild;
            }
        }).fail(function () {
            console.error(`Unable to detect the current application version`);
        }).always(function () {
            me.render();
        });
    },

    /**
     *
     */
    render: function () {
        var me = this;

        // Render template and set some styling
        // ====================================

        if (typeof window.vidiConfig.template === "undefined") {
            tmpl = "default.tmpl";
        } else {
            tmpl = window.vidiConfig.template;
        }

        // Check if template is set in URL vars
        // ====================================

        if (typeof urlVars.tmpl !== "undefined") {
            var par = urlVars.tmpl.split("#");
            if (par.length > 1) {
                par.pop();
            }
            tmpl = par.join();
        }

        // If px and py is provided for print templates,
        // add the values to the dict before rendering
        // =============================================

        if (urlVars.px && urlVars.py) {
            gc2i18n.dict.printWidth = urlVars.px + "px";
            gc2i18n.dict.printHeight = urlVars.py + "px";
            gc2i18n.dict.printDataTime = decodeURIComponent(urlVars.td); // TODO typo
            gc2i18n.dict.printDateTime = decodeURIComponent(urlVars.td);
            gc2i18n.dict.printDate = decodeURIComponent(urlVars.d);
            window.vidiTimeout = 1000;
        } else {
            window.vidiTimeout = 0;
        }

        if (urlVars.l) {
            gc2i18n.dict._showLegend = urlVars.l;
        }
        gc2i18n.dict._showHeader = urlVars.h || "inline";
        gc2i18n.dict.brandName = window.vidiConfig.brandName;
        gc2i18n.dict.aboutBox = window.vidiConfig.aboutBox;

        // Render the page
        // ===============

        if (typeof Templates[tmpl] !== "undefined") {
            $("#main-container").html(Templates[tmpl].render(gc2i18n.dict));
            console.info("Using pre-processed template: " + tmpl);
            me.startApp();
        } else {
            $.get("/api/template/" + urlparser.db + "/" + tmpl, function (template) {
                var rendered = Mustache.render(template, gc2i18n.dict);
                $("#main-container").html(rendered);
                console.info("Loaded external template: " + tmpl);
                me.startApp();
            }).fail(function () {
                alert("Could not load template: " + tmpl);
            })
        }
    },

    /**
     *
     */
    startApp: function () {

        // Load style sheet
        //===================

        $('<link/>').attr({
            rel: 'stylesheet',
            type: 'text/css',
            href: '/css/styles.css'
        }).appendTo('head');

        // Add the tooltip div
        // ===================

        $("body").append('

');

        // Detect the database and schema
        let splitLocation = window.location.pathname.split(`/`);
        if (splitLocation.length === 4 || splitLocation.length === 5) {
            let database = splitLocation[2];
            let schema = splitLocation[3];
            if (!database || database.length === 0 || !schema || schema.length === 0) {
                console.warn(`Unable to detect current database and schema`);
            } else {
                window.vidiConfig.appDatabase = database;
                window.vidiConfig.appSchema = schema;
            }
        } else {
            console.warn(`Unable to detect current database and schema`);
        }

        // Init the modules
        // ================

        modules.cloud.init();
        modules.state.setExtent();

        // Calling mandatory init method
        [`backboneEvents`, `socketId`, `bindEvent`, `baseLayer`, `infoClick`,
            `advancedInfo`, `draw`, `measurements`, `stateSnapshots`, `print`, `layerTree`].map(name => {
            modules[name].init();
        });

        /**
         * Fetch meta > initialize settings > create layer tree >
         * initialize state > load layers > initialize extensions > finish
         */
        modules.meta.init().then(() => {
            return modules.setting.init();
        }, (error) => {
            console.log(error); // Stacktrace
            alert("Vidi is loaded without schema. Can't set extent or add layers");
            backboneEvents.get().trigger("ready:meta");
        }).then(() => {
            return modules.layerTree.create();
        }).finally(() => {
            modules.state.init().then(() => {

                try {

                // Require search module
                // =====================

                // Hack to compile Glob files. Don´t call this function!
                function ಠ_ಠ() {
                    require('./search/*.js', {glob: true});
                }

                if (typeof vidiConfig.searchModules !== "undefined") {
                    $.each(vidiConfig.searchModules, function (i, v) {
                        modules.search[v] = require('./search/' + v + '.js');
                        modules.search[v].set(modules);
                    });
                    modules.search[window.vidiConfig.enabledSearch].init();
                }

                // Require extensions modules
                // ==========================

                //Hack to compile Glob files. Don´t call this function!
                function ಠ_ಠ() {
                    require('./../../extensions/*/browser/*.js', {glob: true});
                    require('./../../extensions/*/browser/*/*.js', {glob: true});
                }

                if (typeof vidiConfig.extensions !== "undefined" && typeof vidiConfig.extensions.browser !== "undefined") {
                    $.each(vidiConfig.extensions.browser, function (i, v) {
                        modules.extensions[Object.keys(v)[0]] = {};
                        $.each(v[Object.keys(v)[0]], function (n, m) {
                            modules.extensions[Object.keys(v)[0]][m] = require('./../../extensions/' + Object.keys(v)[0] + '/browser/' + m + ".js");
                            modules.extensions[Object.keys(v)[0]][m].set(modules);
                        })
                    });

                    if (typeof window.vidiConfig.enabledExtensions === "object") {
                        let enabledExtensionsCopy = JSON.parse(JSON.stringify(window.vidiConfig.enabledExtensions));
                        $.each(vidiConfig.extensions.browser, function (i, v) {
                            $.each(v[Object.keys(v)[0]], function (n, m) {
                                if (window.vidiConfig.enabledExtensions.indexOf(Object.keys(v)[0]) > -1) {
                                    modules.extensions[Object.keys(v)[0]][m].init();
                                    let enabledExtensionIndex = enabledExtensionsCopy.indexOf(Object.keys(v)[0]);
                                    if (enabledExtensionIndex > -1) {
                                        enabledExtensionsCopy.splice(enabledExtensionIndex, 1);
                                    }
                                }
                            })
                        });

                        if (enabledExtensionsCopy.length > 0) {
                            console.warn('Following extensions need to be enabled, but they were not initially compiled: ' + JSON.stringify(enabledExtensionsCopy));
                        }
                    }
                }

                // Init some GUI stuff after modules are loaded
                // ============================================
                $("[data-toggle=tooltip]").tooltip();

                $.material.init();
                touchScroll(".tab-pane");
                touchScroll("#info-modal-body-wrapper");
                $("#loadscreentext").html(__("Loading data"));
                if (window.vidiConfig.activateMainTab) {
                    setTimeout(function () {
                        $('#main-tabs a[href="#' + window.vidiConfig.activateMainTab + '-content"]').tab('show');
                    }, 200);
                }

                $(window).resize(_.debounce(function () {
                    $("#myNavmenu").offcanvas('hide');
                    setTimeout(function () {
                        modules.cloud.get().map.invalidateSize();
                    }, 100);
                }, 0));

                } catch (e) {
                    console.error("Could not perform application initialization", e.message);
                }
            });
        });

        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/service-worker.bundle.js').then((registration) => {
                console.log('Service worker registration succeeded');
            }).catch(error => {
                console.error(`Unable to register the service worker, please load the application over HTTPS in order to use its full functionality`);
            });
        } else {
            console.warn(`Service workers are not supported in this browser, some features may be unavailable`);
        }

        if (window.localforage) {
            localforage.getItem('appVersion').then(versionValue => {
                localforage.getItem('appExtensionsBuild').then(extensionsBuildValue => {
                    if (versionValue === null) {
                        localforage.setItem('appVersion', window.vidiConfig.appVersion).then(() => {
                            localforage.setItem('appExtensionsBuild', window.vidiConfig.appExtensionsBuild).then(() => {
                                console.log(`Versioning: setting new application version (${window.vidiConfig.appVersion}, ${window.vidiConfig.appExtensionsBuild})`);
                            });
                        }).catch(error => {
                            throw new Error(`Unable to store current application version`);
                        });
                    } else {
                        // If two versions are correctly detected
                        if (semver.valid(window.vidiConfig.appVersion) !== null && semver.valid(versionValue) !== null) {
                            if (semver.gt(window.vidiConfig.appVersion, versionValue) ||
                                (window.vidiConfig.appVersion === versionValue && window.vidiConfig.appExtensionsBuild !== extensionsBuildValue)) {
                                if (confirm(`Update application to the newest version (current: ${versionValue}, extensions: ${extensionsBuildValue}, latest: ${window.vidiConfig.appVersion}, extensions: ${window.vidiConfig.appExtensionsBuild})?`)) {
                                    let unregisteringRequests = [];

                                    // Unregister service worker
                                    navigator.serviceWorker.getRegistrations().then((registrations) => {
                                        for(let registration of registrations) {
                                            console.log(`Versioning: unregistering service worker`, registration);
                                            unregisteringRequests.push(registration.unregister());
                                            registration.unregister();
                                        }
                                    });

                                    Promise.all(unregisteringRequests).then((values) => {
                                        // Clear caches
                                        caches.keys().then(function(names) {
                                            for (let name of names) {
                                                console.log(`Versioning: clearing cache`, name);
                                                caches.delete(name);
                                            }
                                        });

                                        // Remove current app version
                                        localforage.removeItem('appVersion').then(() => {
                                            location.reload();
                                        });
                                    });
                                }
                            } else {
                                console.log('Versioning: new application version is not available');
                            }
                        } else if (typeof value === "undefined" || semver.valid(value) === null) {
                            console.warn(`Seems like current application version is invalid, resetting it`);
                            localforage.setItem('appVersion', '1.0.0').then(() => {}).catch(error => {
                                localforage.setItem('appExtensionsBuild', '0').then(() => {}).catch(error => {
                                    throw new Error(`Unable to store current application version`);
                                });
                            });
                        }
                    }
                });
            });
        } else {
            throw new Error(`localforage is not available`);
        }
    }
};<|endoftext|>