<commit_before>'use strict';

describe('each URL should load the corresponding view', function () {
    let page;

    it('DATA-SELECTION--CARDS', () => {
        page = dp.navigate('DATA-SELECTION--CARDS');

        dp.validate('DATA-SELECTION--CARDS', page);

        expect(page.dashboard.rightColumn.dataSelection.availableFilters.categories(0).header).toBe('Thema\'s');
    });

    it('DATA-SELECTION--TABLE', () => {
        page = dp.navigate('DATA-SELECTION--TABLE');
        const dataSelection = page.dashboard.rightColumn.dataSelection;

        dp.validate('DATA-SELECTION--TABLE', page);

        expect(page.title).toBe('Tabel adressen - Dataportaal');

        expect(dataSelection.header.title).toContain('Adressen');

        expect(dataSelection.availableFilters.categories(0).header).toBe('Stadsdeel');
        expect(dataSelection.availableFilters.categories(0).options(0).label).toBe('Centrum');
        expect(dataSelection.availableFilters.categories(0).options(1).label).toBe('Nieuw-West');

        expect(dataSelection.availableFilters.categories(1).header).toBe('GGW-gebied');
        expect(dataSelection.availableFilters.categories(1).options(0).label).toBe('Bijlmer Centrum');
    });

    it('DETAIL', () => {
        page = dp.navigate('DETAIL');

        dp.validate('DETAIL', page);
    });

    it('LAYER-SELECTION_MAP', () => {
        page = dp.navigate('LAYER-SELECTION_MAP');

        dp.validate('LAYER-SELECTION_MAP', page);
    });

    it('MAP', () => {
        page = dp.navigate('MAP');

        dp.validate('MAP', page);
    });

    it('MAP_DATA-SELECTION', () => {
        dp.authenticate.login('EMPLOYEE');

        page = dp.navigate('MAP_DATA-SELECTION');

        dp.validate('MAP_DATA-SELECTION', page);

        expect(page.dashboard.rightColumn.dataSelection.header.tabs(0).isActive).toBe(true);
        expect(page.dashboard.rightColumn.dataSelection.header.tabs(1).isActive).toBe(false);

        dp.authenticate.logout();
    });

    it('MAP_DETAIL--NUMMERAANDUIDING', () => {
        page = dp.navigate('MAP_DETAIL--NUMMERAANDUIDING');
        const detail = page.dashboard.rightColumn.detail;

        dp.validate('MAP_DETAIL--NUMMERAANDUIDING', page);

        expect(page.title).toMatch('Adres: Maria Austriastraat 730 - Dataportaal');

        expect(detail.nummeraanduiding.nummeraanduidingHeader.glossaryHeader.title)
            .toBe('Maria Austriastraat 730');
        expect(detail.nummeraanduiding.nummeraanduidingHeader.glossaryHeader.subtitle).toBe('Adres');
        expect(detail.nummeraanduiding.descriptionList.term(0)).toBe('Naam openbare ruimte');
        expect(detail.nummeraanduiding.descriptionList.definition(0)).toBe('Maria Austriastraat');
        expect(detail.nummeraanduiding.descriptionList.term(1)).toBe('Huisnummer');
        expect(detail.nummeraanduiding.descriptionList.definition(1)).toBe('730');
        expect(detail.nummeraanduiding.descriptionList.term(2)).toBe('Huisletter');
        expect(detail.nummeraanduiding.descriptionList.definition(2)).toBe('');
        expect(detail.nummeraanduiding.descriptionList.term(3)).toBe('Huisnummertoevoeging');
        expect(detail.nummeraanduiding.descriptionList.definition(3)).toBe('');
        expect(detail.nummeraanduiding.descriptionList.term(4)).toBe('Postcode');
        expect(detail.nummeraanduiding.descriptionList.definition(4)).toBe('1087KH');
        expect(detail.nummeraanduiding.descriptionList.term(5)).toBe('Woonplaats');
        expect(detail.nummeraanduiding.descriptionList.definition(5)).toBe('Amsterdam');
        expect(detail.nummeraanduiding.descriptionList.term(6)).toBe('Status');
        expect(detail.nummeraanduiding.descriptionList.definition(6)).toBe('Naamgeving uitgegeven');

        expect(detail.verblijfsobject.glossaryHeader.subtitle).toBe('Verblijfsobject');
        expect(detail.verblijfsobject.descriptionList.term(0)).toBe('Gebruiksdoel');
        expect(detail.verblijfsobject.descriptionList.definition(0)).toBe('BEST-woning');
        expect(detail.verblijfsobject.descriptionList.term(1)).toBe('Feitelijk gebruik');
        expect(detail.verblijfsobject.descriptionList.definition(1)).toBe('woning');
    });

    it('MAP_SEARCH-RESULTS--LOCATION', () => {
        page = dp.navigate('MAP_SEARCH-RESULTS--LOCATION');
        const searchResults = page.dashboard.rightColumn.searchResults;

        dp.validate('MAP_SEARCH-RESULTS--LOCATION', page);

        expect(page.title)
            .toBe('Resultaten (7) met locatie 121356\.94, 487341\.61 \(52\.3729183, 4\.8931775\) - Dataportaal');

        expect(searchResults.categories(0).header).toBe('Openbare ruimte');
        expect(searchResults.categories(0).list(0).link.label).toBe('Dam');

        expect(searchResults.categories(1).header).toBe('Kadastraal object');
        expect(searchResults.categories(1).list(0).link.label).toBe('ASD04F06685G0000');

        expect(searchResults.categories(2).header).toBe('Gebieden (5)');
        expect(searchResults.categories(2).list(0).link.label).toBe('Bufferzone');
        expect(searchResults.categories(2).list(0).subtype).toBe('(unesco)');
        expect(searchResults.categories(2).list(1).link.label).toBe('Centrum');
        expect(searchResults.categories(2).list(1).subtype).toBe('(stadsdeel)');
        expect(searchResults.categories(2).list(2).link.label).toBe('Centrum-West');
        expect(searchResults.categories(2).list(2).subtype).toBe('(gebiedsgericht werken)');
        expect(searchResults.categories(2).list(3).link.label).toBe('Burgwallen-Oude Zijde');
        expect(searchResults.categories(2).list(3).subtype).toBe('(buurtcombinatie)');
        expect(searchResults.categories(2).list(4).link.label).toBe('Oude Kerk e.o.');
        expect(searchResults.categories(2).list(4).subtype).toBe('(buurt)');
    });

    it('SEARCH-RESULTS--QUERY', () => {
        page = dp.navigate('SEARCH-RESULTS--QUERY');
        const searchResults = page.dashboard.rightColumn.searchResults;

        dp.validate('SEARCH-RESULTS--QUERY', page);

        expect(page.title).toMatch(/Data met 'Oost' - Dataportaal$/);

        expect(searchResults.categories(0).header).toMatch(/^Openbare ruimtes \(\d+\)/);
        expect(searchResults.categories(0).list(0).link.label).toMatch(/Oost/);
        expect(searchResults.categories(0).list(1).link.label).toMatch(/Oost/);
        expect(searchResults.categories(0).list(2).link.label).toMatch(/Oost/);
        expect(searchResults.categories(0).list(9).link.label).toMatch(/Oost/);

        expect(searchResults.categories(1).header).toMatch(/^Adressen \([\d.]+\)$/);
        expect(searchResults.categories(1).list(0).link.label).toMatch(/Oost/);
        expect(searchResults.categories(1).list(9).link.label).toMatch(/Oost/);

        expect(searchResults.categories(2).header).toMatch(/^Gebieden \(\d+\)$/);
    });

    it('MAP_STRAATBEELD--DETAIL', () => {
        page = dp.navigate('MAP_STRAATBEELD--DETAIL');

        dp.validate('MAP_STRAATBEELD--DETAIL', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('MAP_STRAATBEELD--PAGE', () => {
        page = dp.navigate('MAP_STRAATBEELD--PAGE');

        dp.validate('MAP_STRAATBEELD--PAGE', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('MAP_STRAATBEELD--SEARCH-RESULTS', () => {
        page = dp.navigate('MAP_STRAATBEELD--SEARCH-RESULTS');

        dp.validate('MAP_STRAATBEELD--SEARCH-RESULTS', page);

        expect(page.title).toBe('Panorama 121356.94, 487341.61 (52.3729183, 4.8931775) - Dataportaal');
    });

    it('PAGE--HOME', () => {
        page = dp.navigate('PAGE--HOME');

        dp.validate('PAGE--HOME', page);
    });

    it('STRAATBEELD--DETAIL', () => {
        page = dp.navigate('STRAATBEELD--DETAIL');

        dp.validate('STRAATBEELD--DETAIL', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('STRAATBEELD--PAGE', () => {
        page = dp.navigate('STRAATBEELD--PAGE');

        dp.validate('STRAATBEELD--PAGE', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('STRAATBEELD--SEARCH-RESULTS', () => {
        page = dp.navigate('STRAATBEELD--SEARCH-RESULTS');

        dp.validate('STRAATBEELD--SEARCH-RESULTS', page);

        expect(page.title).toBe('Panorama 121356.94, 487341.61 (52.3729183, 4.8931775) - Dataportaal');
    });
});
<commit_msg>fixed buurtcombinatie issue tg-3963<commit_after>'use strict';

describe('each URL should load the corresponding view', function () {
    let page;

    it('DATA-SELECTION--CARDS', () => {
        page = dp.navigate('DATA-SELECTION--CARDS');

        dp.validate('DATA-SELECTION--CARDS', page);

        expect(page.dashboard.rightColumn.dataSelection.availableFilters.categories(0).header).toBe('Thema\'s');
    });

    it('DATA-SELECTION--TABLE', () => {
        page = dp.navigate('DATA-SELECTION--TABLE');
        const dataSelection = page.dashboard.rightColumn.dataSelection;

        dp.validate('DATA-SELECTION--TABLE', page);

        expect(page.title).toBe('Tabel adressen - Dataportaal');

        expect(dataSelection.header.title).toContain('Adressen');

        expect(dataSelection.availableFilters.categories(0).header).toBe('Stadsdeel');
        expect(dataSelection.availableFilters.categories(0).options(0).label).toBe('Centrum');
        expect(dataSelection.availableFilters.categories(0).options(1).label).toBe('Nieuw-West');

        expect(dataSelection.availableFilters.categories(1).header).toBe('GGW-gebied');
        expect(dataSelection.availableFilters.categories(1).options(0).label).toBe('Bijlmer Centrum');
    });

    it('DETAIL', () => {
        page = dp.navigate('DETAIL');

        dp.validate('DETAIL', page);
    });

    it('LAYER-SELECTION_MAP', () => {
        page = dp.navigate('LAYER-SELECTION_MAP');

        dp.validate('LAYER-SELECTION_MAP', page);
    });

    it('MAP', () => {
        page = dp.navigate('MAP');

        dp.validate('MAP', page);
    });

    it('MAP_DATA-SELECTION', () => {
        dp.authenticate.login('EMPLOYEE');

        page = dp.navigate('MAP_DATA-SELECTION');

        dp.validate('MAP_DATA-SELECTION', page);

        expect(page.dashboard.rightColumn.dataSelection.header.tabs(0).isActive).toBe(true);
        expect(page.dashboard.rightColumn.dataSelection.header.tabs(1).isActive).toBe(false);

        dp.authenticate.logout();
    });

    it('MAP_DETAIL--NUMMERAANDUIDING', () => {
        page = dp.navigate('MAP_DETAIL--NUMMERAANDUIDING');
        const detail = page.dashboard.rightColumn.detail;

        dp.validate('MAP_DETAIL--NUMMERAANDUIDING', page);

        expect(page.title).toMatch('Adres: Maria Austriastraat 730 - Dataportaal');

        expect(detail.nummeraanduiding.nummeraanduidingHeader.glossaryHeader.title)
            .toBe('Maria Austriastraat 730');
        expect(detail.nummeraanduiding.nummeraanduidingHeader.glossaryHeader.subtitle).toBe('Adres');
        expect(detail.nummeraanduiding.descriptionList.term(0)).toBe('Naam openbare ruimte');
        expect(detail.nummeraanduiding.descriptionList.definition(0)).toBe('Maria Austriastraat');
        expect(detail.nummeraanduiding.descriptionList.term(1)).toBe('Huisnummer');
        expect(detail.nummeraanduiding.descriptionList.definition(1)).toBe('730');
        expect(detail.nummeraanduiding.descriptionList.term(2)).toBe('Huisletter');
        expect(detail.nummeraanduiding.descriptionList.definition(2)).toBe('');
        expect(detail.nummeraanduiding.descriptionList.term(3)).toBe('Huisnummertoevoeging');
        expect(detail.nummeraanduiding.descriptionList.definition(3)).toBe('');
        expect(detail.nummeraanduiding.descriptionList.term(4)).toBe('Postcode');
        expect(detail.nummeraanduiding.descriptionList.definition(4)).toBe('1087KH');
        expect(detail.nummeraanduiding.descriptionList.term(5)).toBe('Woonplaats');
        expect(detail.nummeraanduiding.descriptionList.definition(5)).toBe('Amsterdam');
        expect(detail.nummeraanduiding.descriptionList.term(6)).toBe('Status');
        expect(detail.nummeraanduiding.descriptionList.definition(6)).toBe('Naamgeving uitgegeven');

        expect(detail.verblijfsobject.glossaryHeader.subtitle).toBe('Verblijfsobject');
        expect(detail.verblijfsobject.descriptionList.term(0)).toBe('Gebruiksdoel');
        expect(detail.verblijfsobject.descriptionList.definition(0)).toBe('BEST-woning');
        expect(detail.verblijfsobject.descriptionList.term(1)).toBe('Feitelijk gebruik');
        expect(detail.verblijfsobject.descriptionList.definition(1)).toBe('woning');
    });

    it('MAP_SEARCH-RESULTS--LOCATION', () => {
        page = dp.navigate('MAP_SEARCH-RESULTS--LOCATION');
        const searchResults = page.dashboard.rightColumn.searchResults;

        dp.validate('MAP_SEARCH-RESULTS--LOCATION', page);

        expect(page.title)
            .toBe('Resultaten (7) met locatie 121356\.94, 487341\.61 \(52\.3729183, 4\.8931775\) - Dataportaal');

        expect(searchResults.categories(0).header).toBe('Openbare ruimte');
        expect(searchResults.categories(0).list(0).link.label).toBe('Dam');

        expect(searchResults.categories(1).header).toBe('Kadastraal object');
        expect(searchResults.categories(1).list(0).link.label).toBe('ASD04F06685G0000');

        expect(searchResults.categories(2).header).toBe('Gebieden (5)');
        expect(searchResults.categories(2).list(0).link.label).toBe('Bufferzone');
        expect(searchResults.categories(2).list(0).subtype).toBe('(unesco)');
        expect(searchResults.categories(2).list(1).link.label).toBe('Centrum');
        expect(searchResults.categories(2).list(1).subtype).toBe('(stadsdeel)');
        expect(searchResults.categories(2).list(2).link.label).toBe('Centrum-West');
        expect(searchResults.categories(2).list(2).subtype).toBe('(gebiedsgericht werken)');
        expect(searchResults.categories(2).list(3).link.label).toBe('Burgwallen-Oude Zijde');
        expect(searchResults.categories(2).list(3).subtype).toBe('(wijk)');
        expect(searchResults.categories(2).list(4).link.label).toBe('Oude Kerk e.o.');
        expect(searchResults.categories(2).list(4).subtype).toBe('(buurt)');
    });

    it('SEARCH-RESULTS--QUERY', () => {
        page = dp.navigate('SEARCH-RESULTS--QUERY');
        const searchResults = page.dashboard.rightColumn.searchResults;

        dp.validate('SEARCH-RESULTS--QUERY', page);

        expect(page.title).toMatch(/Data met 'Oost' - Dataportaal$/);

        expect(searchResults.categories(0).header).toMatch(/^Openbare ruimtes \(\d+\)/);
        expect(searchResults.categories(0).list(0).link.label).toMatch(/Oost/);
        expect(searchResults.categories(0).list(1).link.label).toMatch(/Oost/);
        expect(searchResults.categories(0).list(2).link.label).toMatch(/Oost/);
        expect(searchResults.categories(0).list(9).link.label).toMatch(/Oost/);

        expect(searchResults.categories(1).header).toMatch(/^Adressen \([\d.]+\)$/);
        expect(searchResults.categories(1).list(0).link.label).toMatch(/Oost/);
        expect(searchResults.categories(1).list(9).link.label).toMatch(/Oost/);

        expect(searchResults.categories(2).header).toMatch(/^Gebieden \(\d+\)$/);
    });

    it('MAP_STRAATBEELD--DETAIL', () => {
        page = dp.navigate('MAP_STRAATBEELD--DETAIL');

        dp.validate('MAP_STRAATBEELD--DETAIL', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('MAP_STRAATBEELD--PAGE', () => {
        page = dp.navigate('MAP_STRAATBEELD--PAGE');

        dp.validate('MAP_STRAATBEELD--PAGE', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('MAP_STRAATBEELD--SEARCH-RESULTS', () => {
        page = dp.navigate('MAP_STRAATBEELD--SEARCH-RESULTS');

        dp.validate('MAP_STRAATBEELD--SEARCH-RESULTS', page);

        expect(page.title).toBe('Panorama 121356.94, 487341.61 (52.3729183, 4.8931775) - Dataportaal');
    });

    it('PAGE--HOME', () => {
        page = dp.navigate('PAGE--HOME');

        dp.validate('PAGE--HOME', page);
    });

    it('STRAATBEELD--DETAIL', () => {
        page = dp.navigate('STRAATBEELD--DETAIL');

        dp.validate('STRAATBEELD--DETAIL', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('STRAATBEELD--PAGE', () => {
        page = dp.navigate('STRAATBEELD--PAGE');

        dp.validate('STRAATBEELD--PAGE', page);

        expect(page.title).toBe('Panorama 128708.98, 485100.65 (52.3531791, 5.0013100) - Dataportaal');
    });

    it('STRAATBEELD--SEARCH-RESULTS', () => {
        page = dp.navigate('STRAATBEELD--SEARCH-RESULTS');

        dp.validate('STRAATBEELD--SEARCH-RESULTS', page);

        expect(page.title).toBe('Panorama 121356.94, 487341.61 (52.3729183, 4.8931775) - Dataportaal');
    });
});
<|endoftext|>


<commit_before>var ModAPI = require('modapi')
var _ = require('lodash')
var qml = ModAPI.QMLFile("Event/EventCommands/EventCommand101.qml")

var previewButton = qml.getObjectById("button")
previewButton.node.object("anchors.right", null)
previewButton.node.object("anchors.bottom", null)

var container = previewButton.parent.newObject().createNode()
container.describe = "ControlsRow"
container.object("anchors.right", "parent.right")
container.object("anchors.bottom", "parent.bottom")

var pheButton = container.newObject()
pheButton.createNode().describe = "PluginHelpEverywhereButton"

previewButton.parent = container

qml.save()
<commit_msg>Update EventCommand101.qml.js<commit_after>var ModAPI = require('modapi')
var _ = require('lodash')
var qml = ModAPI.QMLFile("Event/EventCommands/EventCommand101.qml")

var previewButton = qml.root.getObjectById("button")
previewButton.remove("anchors.right")
previewButton.remove("anchors.bottom")
var x = previewButton.parent
var container = ModAPI.QMLCompile("ControlsRow {anchors.right: parent.right; anchors.bottom: parent.bottom; PluginHelpEverywhereButton{} } ")
x.add(container)
container.add(previewButton)

qml.save()
<|endoftext|>


<commit_before>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
// License: GNU General Public License v3. See license.txt

wn.require("app/js/stock_analytics.js");

wn.pages['stock-balance'].onload = function(wrapper) {
	wn.ui.make_app_page({
		parent: wrapper,
		title: 'Stock Balance',
		single_column: true
	});

	new erpnext.StockBalance(wrapper);

	wrapper.appframe.add_home_breadcrumb()
	wrapper.appframe.add_module_icon("Stock")
	wrapper.appframe.add_breadcrumb("icon-bar-chart")
}

erpnext.StockBalance = erpnext.StockAnalytics.extend({
	init: function(wrapper) {
		this._super(wrapper, {
			title: "Stock Balance",
			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
				"Stock Entry", "Project"],
		});
	},
	setup_columns: function() {
		this.columns = [
			{id: "name", name: "Item", field: "name", width: 300,
				formatter: this.tree_formatter},
			{id: "item_name", name: "Item Name", field: "item_name", width: 100},
			{id: "description", name: "Description", field: "description", width: 200,
				formatter: this.text_formatter},
			{id: "brand", name: "Brand", field: "brand", width: 100},
			{id: "stock_uom", name: "UOM", field: "stock_uom", width: 100},
			{id: "opening_qty", name: "Opening Qty", field: "opening_qty", width: 100,
				formatter: this.currency_formatter},
			{id: "inflow_qty", name: "In Qty", field: "inflow_qty", width: 100,
				formatter: this.currency_formatter},
			{id: "outflow_qty", name: "Out Qty", field: "outflow_qty", width: 100,
				formatter: this.currency_formatter},
			{id: "closing_qty", name: "Closing Qty", field: "closing_qty", width: 100,
				formatter: this.currency_formatter},

			{id: "opening_value", name: "Opening Value", field: "opening_value", width: 100,
				formatter: this.currency_formatter},
			{id: "inflow_value", name: "In Value", field: "inflow_value", width: 100,
				formatter: this.currency_formatter},
			{id: "outflow_value", name: "Out Value", field: "outflow_value", width: 100,
				formatter: this.currency_formatter},
			{id: "closing_value", name: "Closing Value", field: "closing_value", width: 100,
				formatter: this.currency_formatter},
		];
	},

	filters: [
		{fieldtype:"Select", label: "Brand", link:"Brand",
			default_value: "Select Brand...", filter: function(val, item, opts) {
				return val == opts.default_value || item.brand == val || item._show;
			}, link_formatter: {filter_input: "brand"}},
		{fieldtype:"Select", label: "Warehouse", link:"Warehouse",
			default_value: "Select Warehouse...", filter: function(val, item, opts, me) {
				return me.apply_zero_filter(val, item, opts, me);
			}},
		{fieldtype:"Select", label: "Project", link:"Project",
			default_value: "Select Project...", filter: function(val, item, opts, me) {
				return me.apply_zero_filter(val, item, opts, me);
			}, link_formatter: {filter_input: "project"}},
		{fieldtype:"Date", label: "From Date"},
		{fieldtype:"Label", label: "To"},
		{fieldtype:"Date", label: "To Date"},
		{fieldtype:"Button", label: "Refresh", icon:"icon-refresh icon-white", cssClass:"btn-info"},
		{fieldtype:"Button", label: "Reset Filters"}
	],

	setup_plot_check: function() {
		return;
	},

	prepare_data: function() {
		this.stock_entry_map = this.make_name_map(wn.report_dump.data["Stock Entry"], "name");
		this._super();
	},

	prepare_balances: function() {
		var me = this;
		var from_date = dateutil.str_to_obj(this.from_date);
		var to_date = dateutil.str_to_obj(this.to_date);
		var data = wn.report_dump.data["Stock Ledger Entry"];

		this.item_warehouse = {};
		this.serialized_buying_rates = this.get_serialized_buying_rates();

		for(var i=0, j=data.length; i<j; i++) {
			var sl = data[i];
			var sl_posting_date = dateutil.str_to_obj(sl.posting_date);

			if((me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) &&
				(me.is_default("project") ? true : me.project == sl.project)) {
				var item = me.item_by_name[sl.item_code];
				var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
				var valuation_method = item.valuation_method ?
					item.valuation_method : sys_defaults.valuation_method;
				var is_fifo = valuation_method == "FIFO";

				var qty_diff = sl.qty;
				var value_diff = me.get_value_diff(wh, sl, is_fifo);

				if(sl_posting_date < from_date) {
					item.opening_qty += qty_diff;
					item.opening_value += value_diff;
				} else if(sl_posting_date <= to_date) {
					var ignore_inflow_outflow = this.is_default("warehouse")
						&& sl.voucher_type=="Stock Entry"
						&& this.stock_entry_map[sl.voucher_no].purpose=="Material Transfer";

					if(!ignore_inflow_outflow) {
						if(qty_diff < 0) {
							item.outflow_qty += Math.abs(qty_diff);
						} else {
							item.inflow_qty += qty_diff;
						}
						if(value_diff < 0) {
							item.outflow_value += Math.abs(value_diff);
						} else {
							item.inflow_value += value_diff;
						}
					}

					item.closing_qty += qty_diff;
					item.closing_value += value_diff;
				} else {
					break;
				}
			}
		}

		// opening + diff = closing
		// adding opening, since diff already added to closing
		$.each(me.item_by_name, function(key, item) {
			item.closing_qty += item.opening_qty;
			item.closing_value += item.opening_value;
		});
	},

	update_groups: function() {
		var me = this;

		$.each(this.data, function(i, item) {
			// update groups
			if(!item.is_group && me.apply_filter(item, "brand")) {
				var parent = me.parent_map[item.name];
				while(parent) {
					parent_group = me.item_by_name[parent];
					$.each(me.columns, function(c, col) {
						if (col.formatter == me.currency_formatter) {
							parent_group[col.field] =
								flt(parent_group[col.field])
								+ flt(item[col.field]);
						}
					});

					// show parent if filtered by brand
					if(item.brand == me.brand)
						parent_group._show = true;

					parent = me.parent_map[parent];
				}
			}
		});
	},

	get_plot_data: function() {
		return;
	}
});<commit_msg>fix translate stock_balance.js<commit_after>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
// License: GNU General Public License v3. See license.txt

wn.require("app/js/stock_analytics.js");

wn.pages['stock-balance'].onload = function(wrapper) {
	wn.ui.make_app_page({
		parent: wrapper,
		title: wn._('Stock Balance'),
		single_column: true
	});

	new erpnext.StockBalance(wrapper);

	wrapper.appframe.add_home_breadcrumb()
	wrapper.appframe.add_module_icon("Stock")
	wrapper.appframe.add_breadcrumb("icon-bar-chart")
}

erpnext.StockBalance = erpnext.StockAnalytics.extend({
	init: function(wrapper) {
		this._super(wrapper, {
			title: wn._("Stock Balance"),
			doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
				"Stock Entry", "Project"],
		});
	},
	setup_columns: function() {
		this.columns = [
			{id: "name", name: wn._("Item"), field: "name", width: 300,
				formatter: this.tree_formatter},
			{id: "item_name", name: wn._("Item Name"), field: "item_name", width: 100},
			{id: "description", name: wn._("Description"), field: "description", width: 200,
				formatter: this.text_formatter},
			{id: "brand", name: wn._("Brand"), field: "brand", width: 100},
			{id: "stock_uom", name: wn._("UOM"), field: "stock_uom", width: 100},
			{id: "opening_qty", name: wn._("Opening Qty"), field: "opening_qty", width: 100,
				formatter: this.currency_formatter},
			{id: "inflow_qty", name: wn._("In Qty"), field: "inflow_qty", width: 100,
				formatter: this.currency_formatter},
			{id: "outflow_qty", name: wn._("Out Qty"), field: "outflow_qty", width: 100,
				formatter: this.currency_formatter},
			{id: "closing_qty", name: wn._("Closing Qty"), field: "closing_qty", width: 100,
				formatter: this.currency_formatter},

			{id: "opening_value", name: wn._("Opening Value"), field: "opening_value", width: 100,
				formatter: this.currency_formatter},
			{id: "inflow_value", name: wn._("In Value"), field: "inflow_value", width: 100,
				formatter: this.currency_formatter},
			{id: "outflow_value", name: wn._("Out Value"), field: "outflow_value", width: 100,
				formatter: this.currency_formatter},
			{id: "closing_value", name: wn._("Closing Value"), field: "closing_value", width: 100,
				formatter: this.currency_formatter},
		];
	},

	filters: [
		{fieldtype:"Select", label: wn._("Brand"), link:"Brand",
			default_value: "Select Brand...", filter: function(val, item, opts) {
				return val == opts.default_value || item.brand == val || item._show;
			}, link_formatter: {filter_input: "brand"}},
		{fieldtype:"Select", label: wn._("Warehouse"), link:"Warehouse",
			default_value: "Select Warehouse...", filter: function(val, item, opts, me) {
				return me.apply_zero_filter(val, item, opts, me);
			}},
		{fieldtype:"Select", label: wn._("Project"), link:"Project",
			default_value: "Select Project...", filter: function(val, item, opts, me) {
				return me.apply_zero_filter(val, item, opts, me);
			}, link_formatter: {filter_input: "project"}},
		{fieldtype:"Date", label: wn._("From Date")},
		{fieldtype:"Label", label: wn._("To")},
		{fieldtype:"Date", label: wn._("To Date")},
		{fieldtype:"Button", label: wn._("Refresh"), icon:"icon-refresh icon-white", cssClass:"btn-info"},
		{fieldtype:"Button", label: wn._("Reset Filters")}
	],

	setup_plot_check: function() {
		return;
	},

	prepare_data: function() {
		this.stock_entry_map = this.make_name_map(wn.report_dump.data["Stock Entry"], "name");
		this._super();
	},

	prepare_balances: function() {
		var me = this;
		var from_date = dateutil.str_to_obj(this.from_date);
		var to_date = dateutil.str_to_obj(this.to_date);
		var data = wn.report_dump.data["Stock Ledger Entry"];

		this.item_warehouse = {};
		this.serialized_buying_rates = this.get_serialized_buying_rates();

		for(var i=0, j=data.length; i<j; i++) {
			var sl = data[i];
			var sl_posting_date = dateutil.str_to_obj(sl.posting_date);

			if((me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) &&
				(me.is_default("project") ? true : me.project == sl.project)) {
				var item = me.item_by_name[sl.item_code];
				var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
				var valuation_method = item.valuation_method ?
					item.valuation_method : sys_defaults.valuation_method;
				var is_fifo = valuation_method == "FIFO";

				var qty_diff = sl.qty;
				var value_diff = me.get_value_diff(wh, sl, is_fifo);

				if(sl_posting_date < from_date) {
					item.opening_qty += qty_diff;
					item.opening_value += value_diff;
				} else if(sl_posting_date <= to_date) {
					var ignore_inflow_outflow = this.is_default("warehouse")
						&& sl.voucher_type=="Stock Entry"
						&& this.stock_entry_map[sl.voucher_no].purpose=="Material Transfer";

					if(!ignore_inflow_outflow) {
						if(qty_diff < 0) {
							item.outflow_qty += Math.abs(qty_diff);
						} else {
							item.inflow_qty += qty_diff;
						}
						if(value_diff < 0) {
							item.outflow_value += Math.abs(value_diff);
						} else {
							item.inflow_value += value_diff;
						}
					}

					item.closing_qty += qty_diff;
					item.closing_value += value_diff;
				} else {
					break;
				}
			}
		}

		// opening + diff = closing
		// adding opening, since diff already added to closing
		$.each(me.item_by_name, function(key, item) {
			item.closing_qty += item.opening_qty;
			item.closing_value += item.opening_value;
		});
	},

	update_groups: function() {
		var me = this;

		$.each(this.data, function(i, item) {
			// update groups
			if(!item.is_group && me.apply_filter(item, "brand")) {
				var parent = me.parent_map[item.name];
				while(parent) {
					parent_group = me.item_by_name[parent];
					$.each(me.columns, function(c, col) {
						if (col.formatter == me.currency_formatter) {
							parent_group[col.field] =
								flt(parent_group[col.field])
								+ flt(item[col.field]);
						}
					});

					// show parent if filtered by brand
					if(item.brand == me.brand)
						parent_group._show = true;

					parent = me.parent_map[parent];
				}
			}
		});
	},

	get_plot_data: function() {
		return;
	}
});<|endoftext|>


<commit_before>// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {

define('State', ['logme'], function (logme) {
    var stateInst;

    // Since there will be (can be) multiple GST on a page, and each will have
    // a separate state, we will create a factory constructor function. The
    // constructor will expect the ID of the DIV with the GST contents, and the
    // configuration object (parsed from a JSON string). It will return an
    // object containing methods to set and get the private state properties.

    stateInst = 0;

    // This module defines and returns a factory constructor.
    return State;

    function State(gstId, config) {
        var parameters, allParameterNames, allParameterValues,
            plotDiv, dynamicEl;

        dynamicEl = [];

        stateInst += 1;
        logme('MESSAGE: Creating state instance # ' + stateInst + '.');

        // Initially, there are no parameters to track. So, we will instantiate
        // an empty object.
        //
        // As we parse the JSON config object, we will add parameters as
        // named properties. For example
        //
        //     parameters.a = {...};
        //
        // will be created for the parameter 'a'.
        parameters = {};

        // Check that the required parameters config object is available.
        if ($.isPlainObject(config.parameters) === false) {
            logme('ERROR: Expected config.parameters to be an object. It is not.');
            logme('config.parameters = ', config.parameters);

            return;
        }

        // If config.parameters.param is an array, pass it to the processor
        // element by element.
        if ($.isArray(config.parameters.param) === true) {
            (function (c1) {
                while (c1 < config.parameters.param.length) {
                    processParameter(config.parameters.param[c1]);
                    c1 += 1;
                }
            }(0));
        }

        // If config.parameters.param is an object, pass this object to the
        // processor directly.
        else if ($.isPlainObject(config.parameters.param) === true) {
            processParameter(config.parameters.param);
        }

        // If config.parameters.param is some other type, report an error and
        // do not continue.
        else {
            logme('ERROR: config.parameters.param is of an unsupported type.');
            logme('config.parameters.param = ', config.parameters.param);

            return;
        }

        // Instead of building these arrays every time when some component
        // requests them, we will create them in the beginning, and then update
        // each element individually when some parameter's value changes.
        //
        // Then we can just return the required array, instead of iterating
        // over all of the properties of the 'parameters' object, and
        // extracting their names/values one by one.
        allParameterNames = [];
        allParameterValues = [];

        // Populate 'allParameterNames', and 'allParameterValues' with data.
        generateHelperArrays();

        // The constructor will return an object with methods to operate on
        // it's private properties.
        return {
            'getParameterValue': getParameterValue,
            'setParameterValue': setParameterValue,

            'getParamObj': getParamObj,

            'getAllParameterNames': getAllParameterNames,
            'getAllParameterValues': getAllParameterValues,

            'bindUpdatePlotEvent': bindUpdatePlotEvent,
            'addDynamicEl': addDynamicEl
        };

        function getAllParameterNames() {
            return allParameterNames;
        }

        function getAllParameterValues() {
            return allParameterValues;
        }

        function getParamObj(paramName) {
            if (parameters.hasOwnProperty(paramName) === false) {
                logme('ERROR: Object parameters does not have a property named "' + paramName + '".');

                return;
            }

            return parameters[paramName];
        }

        function bindUpdatePlotEvent(newPlotDiv, callback) {
            plotDiv = newPlotDiv;

            plotDiv.bind('update_plot', callback);
        }

        function addDynamicEl(outputEl, func) {
            dynamicEl.push({
                'outputEl': outputEl,
                'func': func
            });
        }

        function getParameterValue(paramName) {

            // If the name of the constant is not tracked by state, return an
            // 'undefined' value.
            if (parameters.hasOwnProperty(paramName) === false) {
                logme('ERROR: Object parameters does not have a property named "' + paramName + '".');

                return;
            }

            return parameters[paramname].value;
        }

        // ####################################################################
        //
        // Function: setParameterValue(paramName, paramValue, element)
        // --------------------------------------------------
        //
        //
        // This function can be called from a callback, registered by a slider
        // or a text input, when specific events ('slide' or 'change') are
        // triggered.
        //
        // The 'paramName' is the name of the parameter in 'parameters' object
        // whose value must be updated to the new value of 'paramValue'.
        //
        // Before we update the value, we must check that:
        //
        //     1.) the parameter named as 'paramName' actually exists in the
        //         'parameters' object;
        //     2.) the value 'paramValue' is a valid floating-point number, and
        //         it lies within the range specified by the 'min' and 'max'
        //         properties of the stored parameter object.
        //
        // If 'paramName' and 'paramValue' turn out to be valid, we will update
        // the stored value in the parameter with the new value, and also
        // update all of the text inputs and the slider that correspond to this
        // parameter (if any), so that they reflect the new parameter's value.
        // Finally, the helper array 'allParameterValues' will also be updated
        // to reflect the change.
        //
        // If something went wrong (for example the new value is outside the
        // allowed range), then we will reset the 'element' to display the
        // original value.
        //
        // ####################################################################
        function setParameterValue(paramName, paramValue, element, slider) {
            var paramValueNum, c1;

            // If a parameter with the name specified by the 'paramName'
            // parameter is not tracked by state, do not do anything.
            if (parameters.hasOwnProperty(paramName) === false) {
                logme('ERROR: Object parameters does not have a property named "' + paramName + '".');

                return;
            }

            // Try to convert the passed value to a valid floating-point
            // number.
            paramValueNum = parseFloat(paramValue);

            // We are interested only in valid float values. NaN, -INF,
            // +INF we will disregard.
            if (isFinite(paramValueNum) === false) {
                logme('ERROR: New parameter value is not a floating-point number.');
                logme('paramValue = ', paramValue);

                return;
            }

            if (paramValueNum < parameters[paramName].min) {
                paramValueNum = parameters[paramName].min;
            } else if (paramValueNum > parameters[paramName].max) {
                paramValueNum = parameters[paramName].max;
            }

            parameters[paramName].value = paramValueNum;

            // If we have a plot DIV to work with, tell to update.
            if (plotDiv !== undefined) {
                plotDiv.trigger('update_plot');
            }

            // Update all text inputs with the new parameter's value.
            for (c1 = 0; c1 < parameters[paramName].inputDivs.length; c1 += 1) {
                parameters[paramName].inputDivs[c1].val(paramValueNum);
            }

            // Update the single slider with the new parameter's value.
            if (parameters[paramName].sliderDiv !== null) {
                parameters[paramName].sliderDiv.slider('value', paramValueNum);
            }

            // Update the helper array with the new parameter's value.
            allParameterValues[parameters[paramName].helperArrayIndex] = paramValueNum;

            for (c1 = 0; c1 < dynamicEl.length; c1++) {
                dynamicEl[c1].outputEl.html(dynamicEl[c1].func.apply(window, allParameterValues));
            }

            return true;
        } // End-of: function setParameterValue

        // ####################################################################
        //
        // Function: processParameter(obj)
        // -------------------------------
        //
        //
        // This function will be run once for each instance of a GST when
        // parsing the JSON config object.
        //
        // 'newParamObj' must be empty from the start for each invocation of
        // this function, that's why we will declare it locally.
        //
        // We will parse the passed object 'obj' and populate the 'newParamObj'
        // object with required properties.
        //
        // Since there will be many properties that are of type floating-point
        // number, we will have a separate function for parsing them.
        //
        // processParameter() will fail right away if 'obj' does not have a
        // '@var' property which represents the name of the parameter we want
        // to process.
        //
        // If, after all of the properties have been processed, we reached the
        // end of the function successfully, the 'newParamObj' will be added to
        // the 'parameters' object (that is defined in the scope of State()
        // function) as a property named as the name of the parameter.
        //
        // If at least one of the properties from 'obj' does not get correctly
        // parsed, then the parameter represented by 'obj' will be disregarded.
        // It will not be available to user-defined plotting functions, and
        // things will most likely break. We will notify the user about this.
        //
        // ####################################################################
        function processParameter(obj) {
            var paramName, newParamObj;

            if (typeof obj['@var'] !== 'string') {
                logme('ERROR: Expected obj["@var"] to be a string. It is not.');
                logme('obj["@var"] = ', obj['@var']);

                return;
            }

            paramName = obj['@var'];
            newParamObj = {};

            if (
                (processFloat('@min', 'min') === false) ||
                (processFloat('@max', 'max') === false) ||
                (processFloat('@step', 'step') === false) ||
                (processFloat('@initial', 'value') === false)
            ) {
                logme('ERROR: A required property is missing. Not creating parameter "' + paramName + '"');

                return;
            }

            // Pointers to text input and slider DIV elements that this
            // parameter will be attached to. Initially there are none. When we
            // will create text inputs and sliders, we will update these
            // properties.
            newParamObj.inputDivs = [];
            newParamObj.sliderDiv = null;

            // Everything went well, so save the new parameter object.
            parameters[paramName] = newParamObj;

            return;

            function processFloat(attrName, newAttrName) {
                var attrValue;

                if (typeof obj[attrName] !== 'string') {
                    logme('ERROR: Expected obj["' + attrName + '"] to be a string. It is not.');
                    logme('obj["' + attrName + '"] = ', obj[attrName]);

                    return false;
                } else {
                    attrValue = parseFloat(obj[attrName]);

                    if (isFinite(attrValue) === false) {
                        logme('ERROR: Expected obj["' + attrName + '"] to be a valid floating-point number. It is not.');
                        logme('obj["' + attrName + '"] = ', obj[attrName]);

                        return false;
                    }
                }

                newParamObj[newAttrName] = attrValue;

                return true;
            } // End-of: function processFloat
        } // End-of: function processParameter

        // ####################################################################
        //
        // Function: generateHelperArrays()
        // -------------------------------
        //
        //
        // Populate 'allParameterNames' and 'allParameterValues' with data.
        // Link each parameter object with the corresponding helper array via
        // an index 'helperArrayIndex'. It will be the same for both of the
        // arrays.
        //
        // NOTE: It is important to remember to update these helper arrays
        // whenever a new parameter is added (or one is removed), or when a
        // parameter's value changes.
        //
        // ####################################################################
        function generateHelperArrays() {
            var paramName, c1;

            c1 = 0;
            for (paramName in parameters) {
                allParameterNames.push(paramName);
                allParameterValues.push(parameters[paramName].value);

                parameters[paramName].helperArrayIndex = c1;

                c1 += 1;
            }
        }
    } // End-of: function State
});

// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
<commit_msg>Fixed bug. Specified values that are outside the allowed range now behave properly. Plot is redrawn after the value has been set to max (or min) value.<commit_after>// Wrapper for RequireJS. It will make the standard requirejs(), require(), and
// define() functions from Require JS available inside the anonymous function.
(function (requirejs, require, define) {

define('State', ['logme'], function (logme) {
    var stateInst;

    // Since there will be (can be) multiple GST on a page, and each will have
    // a separate state, we will create a factory constructor function. The
    // constructor will expect the ID of the DIV with the GST contents, and the
    // configuration object (parsed from a JSON string). It will return an
    // object containing methods to set and get the private state properties.

    stateInst = 0;

    // This module defines and returns a factory constructor.
    return State;

    function State(gstId, config) {
        var parameters, allParameterNames, allParameterValues,
            plotDiv, dynamicEl;

        dynamicEl = [];

        stateInst += 1;
        logme('MESSAGE: Creating state instance # ' + stateInst + '.');

        // Initially, there are no parameters to track. So, we will instantiate
        // an empty object.
        //
        // As we parse the JSON config object, we will add parameters as
        // named properties. For example
        //
        //     parameters.a = {...};
        //
        // will be created for the parameter 'a'.
        parameters = {};

        // Check that the required parameters config object is available.
        if ($.isPlainObject(config.parameters) === false) {
            logme('ERROR: Expected config.parameters to be an object. It is not.');
            logme('config.parameters = ', config.parameters);

            return;
        }

        // If config.parameters.param is an array, pass it to the processor
        // element by element.
        if ($.isArray(config.parameters.param) === true) {
            (function (c1) {
                while (c1 < config.parameters.param.length) {
                    processParameter(config.parameters.param[c1]);
                    c1 += 1;
                }
            }(0));
        }

        // If config.parameters.param is an object, pass this object to the
        // processor directly.
        else if ($.isPlainObject(config.parameters.param) === true) {
            processParameter(config.parameters.param);
        }

        // If config.parameters.param is some other type, report an error and
        // do not continue.
        else {
            logme('ERROR: config.parameters.param is of an unsupported type.');
            logme('config.parameters.param = ', config.parameters.param);

            return;
        }

        // Instead of building these arrays every time when some component
        // requests them, we will create them in the beginning, and then update
        // each element individually when some parameter's value changes.
        //
        // Then we can just return the required array, instead of iterating
        // over all of the properties of the 'parameters' object, and
        // extracting their names/values one by one.
        allParameterNames = [];
        allParameterValues = [];

        // Populate 'allParameterNames', and 'allParameterValues' with data.
        generateHelperArrays();

        // The constructor will return an object with methods to operate on
        // it's private properties.
        return {
            'getParameterValue': getParameterValue,
            'setParameterValue': setParameterValue,

            'getParamObj': getParamObj,

            'getAllParameterNames': getAllParameterNames,
            'getAllParameterValues': getAllParameterValues,

            'bindUpdatePlotEvent': bindUpdatePlotEvent,
            'addDynamicEl': addDynamicEl
        };

        function getAllParameterNames() {
            return allParameterNames;
        }

        function getAllParameterValues() {
            return allParameterValues;
        }

        function getParamObj(paramName) {
            if (parameters.hasOwnProperty(paramName) === false) {
                logme('ERROR: Object parameters does not have a property named "' + paramName + '".');

                return;
            }

            return parameters[paramName];
        }

        function bindUpdatePlotEvent(newPlotDiv, callback) {
            plotDiv = newPlotDiv;

            plotDiv.bind('update_plot', callback);
        }

        function addDynamicEl(outputEl, func) {
            dynamicEl.push({
                'outputEl': outputEl,
                'func': func
            });
        }

        function getParameterValue(paramName) {

            // If the name of the constant is not tracked by state, return an
            // 'undefined' value.
            if (parameters.hasOwnProperty(paramName) === false) {
                logme('ERROR: Object parameters does not have a property named "' + paramName + '".');

                return;
            }

            return parameters[paramname].value;
        }

        // ####################################################################
        //
        // Function: setParameterValue(paramName, paramValue, element)
        // --------------------------------------------------
        //
        //
        // This function can be called from a callback, registered by a slider
        // or a text input, when specific events ('slide' or 'change') are
        // triggered.
        //
        // The 'paramName' is the name of the parameter in 'parameters' object
        // whose value must be updated to the new value of 'paramValue'.
        //
        // Before we update the value, we must check that:
        //
        //     1.) the parameter named as 'paramName' actually exists in the
        //         'parameters' object;
        //     2.) the value 'paramValue' is a valid floating-point number, and
        //         it lies within the range specified by the 'min' and 'max'
        //         properties of the stored parameter object.
        //
        // If 'paramName' and 'paramValue' turn out to be valid, we will update
        // the stored value in the parameter with the new value, and also
        // update all of the text inputs and the slider that correspond to this
        // parameter (if any), so that they reflect the new parameter's value.
        // Finally, the helper array 'allParameterValues' will also be updated
        // to reflect the change.
        //
        // If something went wrong (for example the new value is outside the
        // allowed range), then we will reset the 'element' to display the
        // original value.
        //
        // ####################################################################
        function setParameterValue(paramName, paramValue, element, slider) {
            var paramValueNum, c1;

            // If a parameter with the name specified by the 'paramName'
            // parameter is not tracked by state, do not do anything.
            if (parameters.hasOwnProperty(paramName) === false) {
                logme('ERROR: Object parameters does not have a property named "' + paramName + '".');

                return;
            }

            // Try to convert the passed value to a valid floating-point
            // number.
            paramValueNum = parseFloat(paramValue);

            // We are interested only in valid float values. NaN, -INF,
            // +INF we will disregard.
            if (isFinite(paramValueNum) === false) {
                logme('ERROR: New parameter value is not a floating-point number.');
                logme('paramValue = ', paramValue);

                return;
            }

            if (paramValueNum < parameters[paramName].min) {
                paramValueNum = parameters[paramName].min;
            } else if (paramValueNum > parameters[paramName].max) {
                paramValueNum = parameters[paramName].max;
            }

            parameters[paramName].value = paramValueNum;

            // Update all text inputs with the new parameter's value.
            for (c1 = 0; c1 < parameters[paramName].inputDivs.length; c1 += 1) {
                parameters[paramName].inputDivs[c1].val(paramValueNum);
            }

            // Update the single slider with the new parameter's value.
            if (parameters[paramName].sliderDiv !== null) {
                parameters[paramName].sliderDiv.slider('value', paramValueNum);
            }

            // Update the helper array with the new parameter's value.
            allParameterValues[parameters[paramName].helperArrayIndex] = paramValueNum;

            for (c1 = 0; c1 < dynamicEl.length; c1++) {
                dynamicEl[c1].outputEl.html(dynamicEl[c1].func.apply(window, allParameterValues));
            }

            // If we have a plot DIV to work with, tell to update.
            if (plotDiv !== undefined) {
                plotDiv.trigger('update_plot');
            }

            return true;
        } // End-of: function setParameterValue

        // ####################################################################
        //
        // Function: processParameter(obj)
        // -------------------------------
        //
        //
        // This function will be run once for each instance of a GST when
        // parsing the JSON config object.
        //
        // 'newParamObj' must be empty from the start for each invocation of
        // this function, that's why we will declare it locally.
        //
        // We will parse the passed object 'obj' and populate the 'newParamObj'
        // object with required properties.
        //
        // Since there will be many properties that are of type floating-point
        // number, we will have a separate function for parsing them.
        //
        // processParameter() will fail right away if 'obj' does not have a
        // '@var' property which represents the name of the parameter we want
        // to process.
        //
        // If, after all of the properties have been processed, we reached the
        // end of the function successfully, the 'newParamObj' will be added to
        // the 'parameters' object (that is defined in the scope of State()
        // function) as a property named as the name of the parameter.
        //
        // If at least one of the properties from 'obj' does not get correctly
        // parsed, then the parameter represented by 'obj' will be disregarded.
        // It will not be available to user-defined plotting functions, and
        // things will most likely break. We will notify the user about this.
        //
        // ####################################################################
        function processParameter(obj) {
            var paramName, newParamObj;

            if (typeof obj['@var'] !== 'string') {
                logme('ERROR: Expected obj["@var"] to be a string. It is not.');
                logme('obj["@var"] = ', obj['@var']);

                return;
            }

            paramName = obj['@var'];
            newParamObj = {};

            if (
                (processFloat('@min', 'min') === false) ||
                (processFloat('@max', 'max') === false) ||
                (processFloat('@step', 'step') === false) ||
                (processFloat('@initial', 'value') === false)
            ) {
                logme('ERROR: A required property is missing. Not creating parameter "' + paramName + '"');

                return;
            }

            // Pointers to text input and slider DIV elements that this
            // parameter will be attached to. Initially there are none. When we
            // will create text inputs and sliders, we will update these
            // properties.
            newParamObj.inputDivs = [];
            newParamObj.sliderDiv = null;

            // Everything went well, so save the new parameter object.
            parameters[paramName] = newParamObj;

            return;

            function processFloat(attrName, newAttrName) {
                var attrValue;

                if (typeof obj[attrName] !== 'string') {
                    logme('ERROR: Expected obj["' + attrName + '"] to be a string. It is not.');
                    logme('obj["' + attrName + '"] = ', obj[attrName]);

                    return false;
                } else {
                    attrValue = parseFloat(obj[attrName]);

                    if (isFinite(attrValue) === false) {
                        logme('ERROR: Expected obj["' + attrName + '"] to be a valid floating-point number. It is not.');
                        logme('obj["' + attrName + '"] = ', obj[attrName]);

                        return false;
                    }
                }

                newParamObj[newAttrName] = attrValue;

                return true;
            } // End-of: function processFloat
        } // End-of: function processParameter

        // ####################################################################
        //
        // Function: generateHelperArrays()
        // -------------------------------
        //
        //
        // Populate 'allParameterNames' and 'allParameterValues' with data.
        // Link each parameter object with the corresponding helper array via
        // an index 'helperArrayIndex'. It will be the same for both of the
        // arrays.
        //
        // NOTE: It is important to remember to update these helper arrays
        // whenever a new parameter is added (or one is removed), or when a
        // parameter's value changes.
        //
        // ####################################################################
        function generateHelperArrays() {
            var paramName, c1;

            c1 = 0;
            for (paramName in parameters) {
                allParameterNames.push(paramName);
                allParameterValues.push(parameters[paramName].value);

                parameters[paramName].helperArrayIndex = c1;

                c1 += 1;
            }
        }
    } // End-of: function State
});

// End of wrapper for RequireJS. As you can see, we are passing
// namespaced Require JS variables to an anonymous function. Within
// it, you can use the standard requirejs(), require(), and define()
// functions as if they were in the global namespace.
}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define)
<|endoftext|>


<commit_before>/*
* @Author: dhananjaysharma
* @Date:   2017-09-02 16:04:43
* @Last Modified by:   dhananjaysharma
* @Last Modified time: 2017-09-02 16:04:57
*/
//probable proxy api handling here
exports.middle = function (request,response,next){
	// console.log('middleware checked');
	next();
}<commit_msg>[update middleware]<commit_after>/*
* @Author: dhananjaysharma
* @Date:   2017-09-02 16:04:43
* @Last Modified by:   dhananjaysharma
* @Last Modified time: 2017-09-02 17:00:33
*/

exports.middle = function (request,response,next){
	next();
}<|endoftext|>


<commit_before>'use strict';

(function () {

  function createCanvas () {
    var canvases = document.getElementsByTagName('canvas');
    var latestCanvas = canvases[canvases.length - 1];

    if (latestCanvas) {
      latestCanvas.id = '';
    }

    var scripts = document.getElementsByTagName('script');
    var latestScript = scripts[scripts.length - 1];

    var newCanvas = document.createElement('canvas');
    newCanvas.id = 'canvas';

    latestScript.parentNode.insertBefore(newCanvas, latestScript);

    return new Canvas(newCanvas);
  }

  window.createCanvas = createCanvas;

})();
<commit_msg>Update create canvas function<commit_after>'use strict';

(function () {

  function createCanvas () {
    var canvases = document.getElementsByTagName('canvas');
    var latestCanvas = canvases[canvases.length - 1];

    if (latestCanvas) {
      latestCanvas.id = '';
    }

    var scripts = document.getElementsByTagName('script');
    var latestScript = scripts[scripts.length - 1];

    var newCanvas = document.createElement('canvas');
    newCanvas.id = 'canvas';

    latestScript.parentNode.insertBefore(newCanvas, latestScript);

    return new Canvasimo(newCanvas);
  }

  window.createCanvas = createCanvas;

})();
<|endoftext|>


<commit_before>var fs = require('fs'),
    express = require('express'),
    moment = require('moment'),
    checklogin = require('../../modules/checklogin.js'),
    isValidDate = require('../../modules/isValidDate.js'),
    router = express.Router();

router.get('/', function(req, res, next) {
    res.redirect('/admin/displays');
});

router.get('/:displayId', function(req, res, next) {
    var displayId = req.params.displayId;
    var login = checklogin(req.session)
    var posterUrls = [];
    if (login) {
        req.getConnection(function(err, connection) {
            var sqlGetFilname = 'SELECT filename FROM posters WHERE '
            var sql = 'SELECT posters FROM slideshows WHERE id IN( SELECT slideshow_id FROM displays WHERE id = ? )';
            // Get the user id using username
            connection.query(sql, [displayId], function(err, match) {
                if (err) {
                    throw err;
                }
                if (match !== '' && match.length > 0) {
                    var posterIds = JSON.parse(match[0].posters);
                    //create string for posters
                      var sqlGetFilname = 'SELECT filename FROM posters WHERE '
                    posterIds.forEach(function(currentValue, index) {
                        if (index === posterIds.length - 1) {
                            sqlGetFilname += 'id = ' + currentValue;
                        } else {
                            sqlGetFilname += 'id = ' + currentValue + ' OR ';
                        }
                    });
                    connection.query(sqlGetFilname, function(err, match) {
                        if (err) {
                            throw err;
                        }
                        if (match !== '' && match.length > 0) {
                            res.render('display/view', {
                                title: 'Display ' + displayId,
                                layout: 'layout/layout2',
                                logedin: login,
                                data: match
                            });
                        } else {
                            res.render('admin/slideshows/show', {
                                title: 'Display ' + displayId,
                                logedin: checklogin(req.session),
                                error: 'There are no posters in your slideshow',
                                data: match
                            });
                        }
                    });

                } else {
                    res.render('admin/slideshows/show', {
                        title: 'Display ' + displayId,
                        logedin: checklogin(req.session),
                        error: 'This display does not exsist ',
                        data: match
                    });
                }
            });
        });
    } else {
        res.redirect('/users/login');
    }
});

// router.get('/:displayID', function(req, res, next) {

//         req.getConnection(function(err, connection) {
//             var sql = 'SELECT id, discription, posters FROM slideshows';
//             // Get the user id using username
//             connection.query(sql, function(err, match) {
//                 if (err) {
//                     throw err;
//                 }
//
//                 if (match !== '' && match.length > 0) {
//                     res.render('admin/slideshows/show', {
//                         title: 'Home',
//                         logedin: checklogin(req.session),
//                         data: match
//                     });
//                 }else{
//                   res.render('admin/slideshows/show', {
//                       title: 'Home',
//                       logedin: checklogin(req.session),
//                       error: 'You have no displays jet',
//                       data: match
//                   });
//                 }
//             });
//         });

// });

module.exports = router;
<commit_msg>fix a layout issuse<commit_after>var fs = require('fs'),
    express = require('express'),
    moment = require('moment'),
    checklogin = require('../../modules/checklogin.js'),
    isValidDate = require('../../modules/isValidDate.js'),
    router = express.Router();

router.get('/', function(req, res, next) {
    res.redirect('/admin/displays');
});

router.get('/:displayId', function(req, res, next) {
    var displayId = req.params.displayId;
    var login = checklogin(req.session)
    var posterUrls = [];
    if (login) {
        req.getConnection(function(err, connection) {
            var sqlGetFilname = 'SELECT filename FROM posters WHERE '
            var sql = 'SELECT posters FROM slideshows WHERE id IN( SELECT slideshow_id FROM displays WHERE id = ? )';
            // Get the user id using username
            connection.query(sql, [displayId], function(err, match) {
                if (err) {
                    throw err;
                }
                if (match !== '' && match.length > 0) {
                    var posterIds = JSON.parse(match[0].posters);
                    //create string for posters
                      var sqlGetFilname = 'SELECT filename FROM posters WHERE '
                    posterIds.forEach(function(currentValue, index) {
                        if (index === posterIds.length - 1) {
                            sqlGetFilname += 'id = ' + currentValue;
                        } else {
                            sqlGetFilname += 'id = ' + currentValue + ' OR ';
                        }
                    });
                    connection.query(sqlGetFilname, function(err, match) {
                        if (err) {
                            throw err;
                        }
                        if (match !== '' && match.length > 0) {
                            res.render('display/view', {
                                title: 'Display ' + displayId,
                                layout: 'layout2',
                                logedin: login,
                                data: match
                            });
                        } else {
                            res.render('admin/slideshows/show', {
                                title: 'Display ' + displayId,
                                logedin: checklogin(req.session),
                                error: 'There are no posters in your slideshow',
                                data: match
                            });
                        }
                    });

                } else {
                    res.render('admin/slideshows/show', {
                        title: 'Display ' + displayId,
                        logedin: checklogin(req.session),
                        error: 'This display does not exsist ',
                        data: match
                    });
                }
            });
        });
    } else {
        res.redirect('/users/login');
    }
});

// router.get('/:displayID', function(req, res, next) {

//         req.getConnection(function(err, connection) {
//             var sql = 'SELECT id, discription, posters FROM slideshows';
//             // Get the user id using username
//             connection.query(sql, function(err, match) {
//                 if (err) {
//                     throw err;
//                 }
//
//                 if (match !== '' && match.length > 0) {
//                     res.render('admin/slideshows/show', {
//                         title: 'Home',
//                         logedin: checklogin(req.session),
//                         data: match
//                     });
//                 }else{
//                   res.render('admin/slideshows/show', {
//                       title: 'Home',
//                       logedin: checklogin(req.session),
//                       error: 'You have no displays jet',
//                       data: match
//                   });
//                 }
//             });
//         });

// });

module.exports = router;
<|endoftext|>


<commit_before>'use strict';

var Address = bitcore.Address;
var PublicKeyRing = copay.PublicKeyRing;
var HDParams = copay.HDParams;
var HDPath = copay.HDPath;

describe('HDParams model', function() {

  it('should create an instance (livenet)', function() {
    var i = new HDParams();
    should.exist(i);
  });

  it('should init indexes', function() {
    var is = HDParams.init(2);
    should.exist(is);
    is.length.should.equal(3);

    var cosigners = is.map(function(i) { return i.copayerIndex; });
    cosigners.indexOf(HDPath.SHARED_INDEX).should.not.equal(-1);
    cosigners.indexOf(0).should.not.equal(-1);
    cosigners.indexOf(1).should.not.equal(-1);
    cosigners.indexOf(2).should.equal(-1);
  });

  it('should serialize to object list and back', function() {
    var is = HDParams.init(3);
    should.exist(is);
    is.length.should.equal(4);

    var list = HDParams.serialize(is);
    list.length.should.equal(4);

    var is2 = HDParams.fromList(list);
    is2.length.should.equal(4);
  });

  it('show be able to store and read', function() {
    var i = new HDParams();
    i.copayerIndex = 1;
    var changeN = 2;
    var addressN = 2;
    for (var j = 0; j < changeN; j++) {
      i.increment(true);
    }
    for (var j = 0; j < addressN; j++) {
      i.increment(false);
    }

    var data = i.toObj();
    should.exist(data);

    var i2 = HDParams.fromObj(data);
    i2.copayerIndex.should.equal(i.copayerIndex);

    i2.getChangeIndex().should.equal(changeN);
    i2.getReceiveIndex().should.equal(addressN);
  });

  it('should count generation indexes', function() {
    var j = new HDParams();
    j.copayerIndex = 1;
    for (var i = 0; i < 3; i++)
    j.increment(true);
    for (var i = 0; i < 2; i++)
    j.increment(false);

    j.changeIndex.should.equal(3);
    j.receiveIndex.should.equal(2);
  });

  it('#merge tests', function() {
    var j = new HDParams();
    j.copayerIndex = 1;

    for (var i = 0; i < 15; i++)
    j.increment(true);
    for (var i = 0; i < 7; i++)
    j.increment(false);
    var j2 = new HDParams({
      copayerIndex: j.copayerIndex,
    });
    j2.merge(j).should.equal(true);
    j2.changeIndex.should.equal(15);
    j2.receiveIndex.should.equal(7);

    j2.merge(j).should.equal(false);
  });

  it('#merge should fail with different copayerIndex index', function() {
    var j1 = new HDParams({ walletId: '1234', copayerIndex: 2 });
    var j2 = new HDParams({ walletId: '1234', copayerIndex: 3 });

    var merge = function() { j2.merge(j1); };
    merge.should.throw(Error);
  })

});
<commit_msg>Add test to HDParams<commit_after>'use strict';

var Address = bitcore.Address;
var PublicKeyRing = copay.PublicKeyRing;
var HDParams = copay.HDParams;
var HDPath = copay.HDPath;

describe('HDParams model', function() {

  it('should create an instance (livenet)', function() {
    var i = new HDParams();
    should.exist(i);
  });

  it('should init indexes', function() {
    var is = HDParams.init(2);
    should.exist(is);
    is.length.should.equal(3);

    var cosigners = is.map(function(i) {
      return i.copayerIndex;
    });
    cosigners.indexOf(HDPath.SHARED_INDEX).should.not.equal(-1);
    cosigners.indexOf(0).should.not.equal(-1);
    cosigners.indexOf(1).should.not.equal(-1);
    cosigners.indexOf(2).should.equal(-1);
  });

  it('should serialize to object list and back', function() {
    var is = HDParams.init(3);
    should.exist(is);
    is.length.should.equal(4);

    var list = HDParams.serialize(is);
    list.length.should.equal(4);

    var is2 = HDParams.fromList(list);
    is2.length.should.equal(4);
  });

  it('should be able to store and read', function() {
    var i = new HDParams();
    i.copayerIndex = 1;
    var changeN = 2;
    var addressN = 2;
    for (var j = 0; j < changeN; j++) {
      i.increment(true);
    }
    for (var j = 0; j < addressN; j++) {
      i.increment(false);
    }

    var data = i.toObj();
    should.exist(data);

    var i2 = HDParams.fromObj(data);
    i2.copayerIndex.should.equal(i.copayerIndex);

    i2.getChangeIndex().should.equal(changeN);
    i2.getReceiveIndex().should.equal(addressN);
  });

  it('should throw an error', function() {
    var data = new HDParams();

    if (data instanceof HDParams) {
      console.log('ok');
    } else {
      console.log('error');
    }
    (function() {
      HDParams.fromObj(data);
    }).should.throw('BADDATA');

  });

  it('should count generation indexes', function() {
    var j = new HDParams();
    j.copayerIndex = 1;
    for (var i = 0; i < 3; i++)
      j.increment(true);
    for (var i = 0; i < 2; i++)
      j.increment(false);

    j.changeIndex.should.equal(3);
    j.receiveIndex.should.equal(2);
  });

  it('#merge tests', function() {
    var j = new HDParams();
    j.copayerIndex = 1;

    for (var i = 0; i < 15; i++)
      j.increment(true);
    for (var i = 0; i < 7; i++)
      j.increment(false);
    var j2 = new HDParams({
      copayerIndex: j.copayerIndex,
    });
    j2.merge(j).should.equal(true);
    j2.changeIndex.should.equal(15);
    j2.receiveIndex.should.equal(7);

    j2.merge(j).should.equal(false);
  });

  it('#merge should fail with different copayerIndex index', function() {
    var j1 = new HDParams({
      walletId: '1234',
      copayerIndex: 2
    });
    var j2 = new HDParams({
      walletId: '1234',
      copayerIndex: 3
    });

    var merge = function() {
      j2.merge(j1);
    };
    merge.should.throw(Error);
  })

});
<|endoftext|>


<commit_before>/*

This module supports "frameback" functionality.

This is useful when there's a master/detail set of pages, and displaying the
master page is expensive.

For example, a Web based email client might have an URL like "/inbox" that
shows a list of emails, and URLs like "/email/1", "/email/2", etc., to show
the contents of a particular email.

Imagine a user is viewing "/inbox", and clicks through to "/email/32", and
then clicks the back button.  The browser will re-request "/inbox" (assuming
it's not cacheable, etc.)  If displaying "/inbox" is slow, the user will be
forced to wait.

One solution to this is to open details pages such as "/email/32" in a new tab
or window.  The back button no longer works, but the window showing "/inbox"
is still there showing the correct content!

This module offers an alternate way to speed up the back button.  Instead of
opening the details view in the same window (replacing the master view), or
opening in a new window, this library opens the details view in an iframe, and
hides the master view.  It uses HTML5 techniques to change the browser URL
without forcing a page reload.  When the user presses the back button, the
details view is hidden and the master view is displayed- instant back button!

In browsers that don't support HTML5 style history manipulation, the
experience is similar, but the back button isn't speeded up.  No iframe is
used and the library gets out of the way.  You can choose to either open in a
new tab or the same tab (by setting the 'target' attribute of anchors.)

You can use this functionality by simply adding a `frameback={true}` attribute
to your `<Link>` element.

The details page linked to need not itself be a triton page.  If it _is_ a
triton page it will have its client-navigation disabled.  Any navigation away
from the details page will result in a full navigation of the outer window
away from the master.  Thus only the master=>details=>back navigation is
speeded up.

*/

var Q      = require('q')
,   logger = require('./logging').getLogger(__LOGGER__)

var {PAGE_CONTENT_NODE_ID} = require('./constants');

// Cover the whole viewport.
var FRAME_STYLE = {
	'border'   : '0px',
	'position' : 'absolute',
	'top'      : '0px',
	'left'     : '0px',
	'width'    : '100%',
	'height'   : '100%',
	'display'  : 'block',
	'zIndex'   : '10',
}

class FramebackController {

	constructor() {
		this.active = false;
		this.masterTitle = document.title; // Let's just stash this away.
	}

	isActive(){
		return this.active;
	}

	navigateTo(url){
		logger.debug(`Navigating to ${url}`);

		this.active = true;

		this.hideMaster();

		if (url !== this.url){
			// We, unfortunately, can't just point the existing
			// frame at a new page since that would be a
			// navigation.  So, we'll destroy it and create a
			// fresh replacement.
			if (this.frame){
				this.destroyFrame();
			}
			this.createFrame(url);
		}
		this.showFrame();

		// Should we wait for the details page to load?
		// I don't think so.  We want the back button to be snappy.
		// If the user clicks back before the page finishes loading
		// we'll just abandon the frame.  If that causes some issue
		// then we'll have to return a promise attached to a deferred
		// that gets resolved in `_handleFrameLoad()`.
		return Q();
	}

	navigateBack(){
		logger.debug(`Navigating back`);
		this.hideFrame();
		this.showMaster();
		this.active = false;
	}

	hideMaster(){
		contentDiv().style.display = 'none';
	}

	showMaster(){
		contentDiv().style.display = 'block';
		document.title = this.masterTitle;
		document.activeElement.blur();
		window.focus();
	}

	createFrame(url){
		this.url = url;
		this.frame = document.createElement("iframe");

		Object.keys(FRAME_STYLE).forEach(k => {
			this.frame.style[k] = FRAME_STYLE[k]
		});

		this.frame.src = absoluteUrl(url);

		document.body.appendChild(this.frame);

		// Can't get the `contentWindow` until it's in the document.
		this.frame.contentWindow.addEventListener(
			'load', this._handleFrameLoad.bind(this, this.frame)
		);

		// Disable triton client navigation in the frame.
		this.frame.contentWindow.__tritonIsFrame = true;
	}

	showFrame(){
		this.frame.style.display = 'block';
		this.frame.contentWindow.focus();
		this.setTitleFromFrame();
	}

	setTitleFromFrame(){
		var doc = this.frame.contentDocument;
		if (doc.title && this.active){
			document.title = doc.title;
		}
	}

	hideFrame(){
		this.frame.style.display = 'none';
	}

	destroyFrame(){
		document.body.removeChild(this.frame);
		this.frame = null;
	}

	_handleFrameLoad(frame){
		// Just in case the user navigated back and to a different
		// frame while we were waiting for the first frame to load.
		if (frame !== this.frame) return;

		[].slice.call(frame.contentDocument.body.querySelectorAll('a')).forEach(link => {
			if (!link.target) link.target = '_top';
		});

		// We've got it now, so let's set it.
		this.setTitleFromFrame();

		logger.debug("Frame loaded");
	}
}

function contentDiv(){
	return document.body.querySelector(`div[${PAGE_CONTENT_NODE_ID}]`);
}

function absoluteUrl(url){
	if (0 === url.indexOf('/')) {
		url = window.location.protocol + '//' + window.location.host + url;
	}
	return url;
}

module.exports = FramebackController;
<commit_msg>Some code level commentary<commit_after>/*

This module supports "frameback" functionality.

This is useful when there's a master/detail set of pages, and displaying the
master page is expensive.

For example, a Web based email client might have an URL like "/inbox" that
shows a list of emails, and URLs like "/email/1", "/email/2", etc., to show
the contents of a particular email.

Imagine a user is viewing "/inbox", and clicks through to "/email/32", and
then clicks the back button.  The browser will re-request "/inbox" (assuming
it's not cacheable, etc.)  If displaying "/inbox" is slow, the user will be
forced to wait.

One solution to this is to open details pages such as "/email/32" in a new tab
or window.  The back button no longer works, but the window showing "/inbox"
is still there showing the correct content!

This module offers an alternate way to speed up the back button.  Instead of
opening the details view in the same window (replacing the master view), or
opening in a new window, this library opens the details view in an iframe, and
hides the master view.  It uses HTML5 techniques to change the browser URL
without forcing a page reload.  When the user presses the back button, the
details view is hidden and the master view is displayed- instant back button!

In browsers that don't support HTML5 style history manipulation, the
experience is similar, but the back button isn't speeded up.  No iframe is
used and the library gets out of the way.  You can choose to either open in a
new tab or the same tab (by setting the 'target' attribute of anchors.)

You can use this functionality by simply adding a `frameback={true}` attribute
to your `<Link>` element.

The details page linked to need not itself be a triton page.  If it _is_ a
triton page it will have its client-navigation disabled.  Any navigation away
from the details page will result in a full navigation of the outer window
away from the master.  Thus only the master=>details=>back navigation is
speeded up.

*/

var Q      = require('q')
,   logger = require('./logging').getLogger(__LOGGER__)

// This is an attribute that's added to the main content div that contains all
// triton elements.
var {PAGE_CONTENT_NODE_ID} = require('./constants');

// Cover the whole viewport.
var FRAME_STYLE = {
	'border'   : '0px',
	'position' : 'absolute',
	'top'      : '0px',
	'left'     : '0px',
	'width'    : '100%',
	'height'   : '100%',
	'display'  : 'block',
	'zIndex'   : '10',
}

class FramebackController {

	constructor() {
		// We'll set this when we're showing the details page.
		this.active = false;

		// When we navigate back from a details page we'll restore the
		// outer page's title to that of the master page.
		this.masterTitle = document.title;
	}

	// Are we currently showing a details page in an iframe?
	isActive(){
		return this.active;
	}

	navigateTo(url){
		logger.debug(`Navigating to ${url}`);

		this.active = true;

		this.hideMaster();

		if (url !== this.url){
			// We, unfortunately, can't just point the existing
			// frame at a new page since that would be a
			// navigation.  So, we'll destroy it and create a
			// fresh replacement.
			if (this.frame){
				this.destroyFrame();
			}
			this.createFrame(url);
		}
		this.showFrame();

		// Should we wait for the details page to load?
		// I don't think so.  We want the back button to be snappy.
		// If the user clicks back before the page finishes loading
		// we'll just abandon the frame.  If that causes some issue
		// then we'll have to return a promise attached to a deferred
		// that gets resolved in `_handleFrameLoad()`.
		return Q();
	}

	navigateBack(){
		logger.debug(`Navigating back`);
		this.hideFrame();
		this.showMaster();
		this.active = false;
	}

	hideMaster(){
		contentDiv().style.display = 'none';
	}

	showMaster(){
		contentDiv().style.display = 'block';
		document.title = this.masterTitle;
		document.activeElement.blur();
		window.focus();
	}

	createFrame(url){
		this.url = url;
		this.frame = document.createElement("iframe");

		Object.keys(FRAME_STYLE).forEach(k => {
			this.frame.style[k] = FRAME_STYLE[k]
		});

		this.frame.src = absoluteUrl(url);

		document.body.appendChild(this.frame);

		// Can't get the `contentWindow` until it's in the document.
		this.frame.contentWindow.addEventListener(
			'load', this._handleFrameLoad.bind(this, this.frame)
		);

		// Disable triton client navigation in the frame.
		this.frame.contentWindow.__tritonIsFrame = true;
	}

	showFrame(){
		this.frame.style.display = 'block';
		this.frame.contentWindow.focus();
		this.setTitleFromFrame();
	}

	setTitleFromFrame(){
		var doc = this.frame.contentDocument;
		if (doc.title && this.active){
			document.title = doc.title;
		}
	}

	hideFrame(){
		this.frame.style.display = 'none';
	}

	destroyFrame(){
		document.body.removeChild(this.frame);
		this.frame = null;
	}

	_handleFrameLoad(frame){
		// Just in case the user navigated back and to a different
		// frame while we were waiting for the first frame to load.
		if (frame !== this.frame) return;

		[].slice.call(frame.contentDocument.body.querySelectorAll('a')).forEach(link => {
			if (!link.target) link.target = '_top';
		});

		// We've got it now, so let's set it.
		this.setTitleFromFrame();

		logger.debug("Frame loaded");
	}
}

function contentDiv(){
	return document.body.querySelector(`div[${PAGE_CONTENT_NODE_ID}]`);
}

function absoluteUrl(url){
	if (0 === url.indexOf('/')) {
		url = window.location.protocol + '//' + window.location.host + url;
	}
	return url;
}

module.exports = FramebackController;
<|endoftext|>


<commit_before>angular.module('main').controller('LivroController', function ($scope, $http) {

    $scope.mesage = {
        text: "",
        type: ""
    };

    $scope.livros = {};

    /*$scope.livros = [{
        titulo:"Casa Blanca",
        descricao:"Casa pintada de blanca",
        imagem:"https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQkj9n0cpj9L5mssR72YffGaviTs_Bt7x2wVi_1CLr7AU8OI6g7hk8zoyo",
    }]*/

    $http.get('buscar').success(function(response){
        $scope.livros = response;
    }).error(function(erro){
        console.log(erro);
    });

    $scope.submeter = function () {
        $http.post('adicionar', $scope.livro)
            .success(function () {
                $scope.mesage.text = 'Livro Adicionado com sucesso';
                $scope.mesage.type = 'success';
            })
            .error(function (erro) {
                $scope.mesage.text = 'Não foi possível adicionar o livro';
                $scope.mesage.type = 'danger';
            })

    }

});
<commit_msg>add controller livros<commit_after>angular.module('main').controller('LivroController', function ($scope, $http) {
    $scope.mesage = {
        text: "",
        type: ""
    };

    $scope.submit = function () {
        if (validate($scope)) {
            $http.post('adicionar', $scope.livro).success(function () {
                createMesage($scope, "Livro cadastrado com Sucesso", "success");
            }).error(function (erro) {
                createMesage($scope, "Não foi cadastrar o livro", "danger");
            })
        }
    }

});

function validate($scope) {
    createMesage($scope, alertInputNull($scope), 'warning');
    return $scope.livro.titulo && $scope.livro.imagem && $scope.livro.descricao;
}

function alertInputNull($scope) {
    if (!$scope.livro.titulo)
        return 'Preencher o titulo';

    if (!$scope.livro.imagem)
        return 'Preencher a imagem';

    if (!$scope.livro.descricao)
        return 'Preencher a descricao';

    return '';
}

function createMesage($scope, mensage, type) {
    $scope.mesage.text = mensage;
    $scope.mesage.type = type;
    setTimeout(function () {
        $scope.$apply(function () {
            $scope.mesage.text = '';
            $scope.mesage.type = '';
        });
    }, 2000);
}

<|endoftext|>