www/js/global.js

Thu, 24 Jan 2019 20:54:45 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 24 Jan 2019 20:54:45 +0100
changeset 200
7b2f11652d67
parent 198
f0ec83e1e01f
child 207
f87ff15be531
permissions
-rw-r--r--

Miscs from bool to ints. Miscs database uses POST instead of GET. Dropdowns are unsing indexes. Dynamic edit screen adjust for weight and liter. Edit screen redesigned. Friendly show duration of ingredients.

/*****************************************************************************
 * Copyright (C) 2014-2019
 *
 * Michiel Broek <mbroek at mbse dot eu>
 *
 * This file is part of BrewCloud
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * BrewCloud is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ThermFerm; see the file COPYING.  If not, write to the Free
 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *****************************************************************************/


// dropdownlists arrays

var StageData = [
	{ id: 0,  en: "Plan",        nl: "Plan" },
	{ id: 1,  en: "Wait",        nl: "Wacht" },
	{ id: 2,  en: "Brew",        nl: "Brouwen" },
	{ id: 3,  en: "Primary",     nl: "Hoofdgisting" },
	{ id: 4,  en: "Secondary",   nl: "Nagisting" },
	{ id: 5,  en: "Tertiary",    nl: "Lagering" },
	{ id: 6,  en: "Package",     nl: "Afvullen" },
	{ id: 7,  en: "Carbonation", nl: "Hergisten" },
	{ id: 8,  en: "Mature",      nl: "Rijpen" },
	{ id: 9,  en: "Taste",       nl: "Proeven" },
	{ id: 10, en: "Ready",       nl: "Gereed" },
	{ id: 11, en: "Closed",      nl: "Afgesloten" }
];
var StageSource = {
	localdata: StageData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var StageAdapter = new $.jqx.dataAdapter(StageSource);

var MaterialData = [
	{ id: 0,  en: "Stainless Steel", nl: "RVS",       sh: 0.11 },
	{ id: 1,  en: "Aluminium",       nl: "Aluminium", sh: 0.22 },
	{ id: 2,  en: "Plastics",        nl: "Kunststof", sh: 0.46 },
	{ id: 3,  en: "Coper",           nl: "Koper",     sh: 0.092 }
];
var MaterialSource = {
	localdata: MaterialData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'sh' }]
};
var MaterialAdapter = new $.jqx.dataAdapter(MaterialSource);

var FermentableTypeData = [
	{ id: 0, en: 'Grain',       nl: 'mout' },
	{ id: 1, en: 'Sugar',       nl: 'suiker' },
	{ id: 2, en: 'Extract',     nl: 'vloeibaar extract' },
	{ id: 3, en: 'Dry extract', nl: 'droog extract' },
	{ id: 4, en: 'Adjunct',     nl: 'ongemout graan' }
];
var FermentableTypeSource = {
	localdata: FermentableTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var FermentableTypeAdapter = new $.jqx.dataAdapter(FermentableTypeSource);

var GrainTypeData = [
	{ id: 0, en: 'Base',      nl: 'basismout' },
	{ id: 1, en: 'Roast',     nl: 'geroosterde mout' },
	{ id: 2, en: 'Crystal',   nl: 'cara- of crystalmout' },
	{ id: 3, en: 'Kilned',    nl: 'geëeste mout'},
	{ id: 4, en: 'Sour malt', nl: 'zuurmout' },
	{ id: 5, en: 'Special',   nl: 'speciale mout' },
	{ id: 6, en: 'No malt',   nl: 'n.v.t.' }
];
var GrainTypeSource = {
	localdata: GrainTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var GrainTypeAdapter = new $.jqx.dataAdapter(GrainTypeSource);

var AddedData = [
	{ id: 0, en: 'Mash', nl: 'maischen' },
	{ id: 1, en: 'Boil', nl: 'koken' },
	{ id: 2, en: 'Fermentation', nl: 'vergisten' },
	{ id: 3, en: 'Lagering', nl: 'nagisten/lageren' },
	{ id: 4, en: 'Bottle', nl: 'bottelen' }
];
var AddedSource = {
	localdata: AddedData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var AddedAdapter = new $.jqx.dataAdapter(AddedSource);

var HopTypeData = [
	{ id: 0, en: 'Bittering', nl: 'bitterhop' },
	{ id: 1, en: 'Aroma',     nl: 'aromahop' },
	{ id: 2, en: 'Both',      nl: 'beide' }
];
var HopTypeSource = {
	localdata: HopTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var HopTypeAdapter = new $.jqx.dataAdapter(HopTypeSource);

var HopFormData = [
	{ id: 0, en: 'Pellet', nl: 'pellets' },
	{ id: 1, en: 'Plug',   nl: 'plugs' },
	{ id: 2, en: 'Leaf',   nl: 'bellen' }
];
var HopFormSource = {
	localdata: HopFormData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
};
var HopFormAdapter = new $.jqx.dataAdapter(HopFormSource);

var YeastTypeData = [
	{ id: 0, en: 'Lager',     nl: 'ondergist' },
	{ id: 1, en: 'Ale',       nl: 'bovengist' },
	{ id: 2, en: 'Wheat',     nl: 'weizengist' },
	{ id: 3, en: 'Wine',      nl: 'wijngist' },
	{ id: 4, en: 'Champagne', nl: 'champagnegist' }
];
var YeastTypeSource = {
	localdata: YeastTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var YeastTypeAdapter = new $.jqx.dataAdapter(YeastTypeSource);

var YeastFormData = [
	{ id: 0, en: 'Liquid',  nl: 'vloeibaar',    cells: 100000000000 },
	{ id: 1, en: 'Dry',     nl: 'droog',        cells: 15000000000 },
	{ id: 2, en: 'Slant',   nl: 'schuine buis', cells: 1700000000 },
	{ id: 3, en: 'Culture', nl: 'slurry',       cells: 1700000000 },
	{ id: 4, en: 'Frozen',  nl: 'ingevroren',   cells: 1700000000 },
	{ id: 5, en: 'Bottle',  nl: 'depot',        cells: 1700000000 }
];
var YeastFormSource = {
	localdata: YeastFormData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var YeastFormAdapter = new $.jqx.dataAdapter(YeastFormSource);

var FlocculationData = [
	{ id: 0, en: 'Low',       nl: 'laag' },
	{ id: 1, en: 'Medium',    nl: 'medium' },
	{ id: 2, en: 'High',      nl: 'hoog' },
	{ id: 3, en: 'Very high', nl: 'zeer hoog' }
];
var FlocculationSource = {
	localdata: FlocculationData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
};
var FlocculationAdapter = new $.jqx.dataAdapter(FlocculationSource);

var StarterTypeData = [
	{ id: 0, en: 'Simple',  nl: 'simpel' },
	{ id: 1, en: 'Aerated', nl: 'belucht' },
	{ id: 2, en: 'Stirred', nl: 'geroerd' }
];
var StarterTypeSource = {
	localdata: StarterTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var StarterTypeAdapter = new $.jqx.dataAdapter(StarterTypeSource);

var MiscTypeData = [
	{ id: 0, en: 'Spice',          nl: 'specerij' },
	{ id: 1, en: 'Herb',           nl: 'kruid' },
	{ id: 2, en: 'Flavor',         nl: 'smaakstof' },
	{ id: 3, en: 'Fining',         nl: 'klaringsmiddel' },
	{ id: 4, en: 'Water agent',    nl: 'brouwzout' },
	{ id: 5, en: 'Yeast nutrient', nl: 'gistvoeding' },
	{ id: 6, en: 'Other',          nl: 'anders' }
];
var MiscTypeSource = {
	localdata: MiscTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var MiscTypeAdapter = new $.jqx.dataAdapter(MiscTypeSource);

var MiscUseData = [
	{ id: 0, en: 'Starter',   nl: 'starter' },
	{ id: 1, en: 'Mash',      nl: 'maischen' },
	{ id: 2, en: 'Boil',      nl: 'koken' },
	{ id: 3, en: 'Primary',   nl: 'hoofdvergisting' },
	{ id: 4, en: 'Secondary', nl: 'nagisting/lagering' },
	{ id: 5, en: 'Bottling',  nl: 'bottelen' }
];
var MiscUseSource = {
	localdata: MiscUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var MiscUseAdapter = new $.jqx.dataAdapter(MiscUseSource);




// options for editors

var Spin1dec1 = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 0,
	decimalDigits: 1,
	spinButtons: true,
	spinButtonsStep: 0.1
};
var Spin1dec5 = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 0,
	decimalDigits: 1,
	spinButtons: true,
	spinButtonsStep: 0.5
};
var SpinpH = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 1,
	max: 14,
	decimalDigits: 1,
	spinButtons: true,
	spinButtonsStep: 0.1
};
var Spin2pH = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 1,
	max: 14,
	decimalDigits: 2,
	spinButtons: true,
	spinButtonsStep: 0.05
};
var YeastT = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 0,
	max: 40,
	decimalDigits: 1,
	spinButtons: true,
	spinButtonsStep: 0.5
};
var PosInt = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 0,
	decimalDigits: 0,
	spinButtons: true,
};
var Perc1dec5 = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 0,
	max: 100,
	decimalDigits: 1,
	spinButtons: true,
	spinButtonsStep: 0.5
};
var Perc1dec1 = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 0,
	max: 100,
	decimalDigits: 1,
	spinButtons: true,
	spinButtonsStep: 0.1
};
var Spin2dec1 = {
	inputMode: 'simple',
	spinMode: 'simple',
	theme: theme,
	width: 110,
	height: 23,
	min: 0,
	decimalDigits: 2,
	spinButtons: true,
	spinButtonsStep: 0.01
};
var Dateopts = {
	theme: theme,
	width: 150,
	height: 23,
	allowNullDate: true,
	todayString: 'Vandaag',
	clearString: 'Wissen',
	showFooter: true,
	formatString: 'yyyy-MM-dd',
	enableBrowserBoundsDetection: true
};


var	sugardensity = 1.611; //kg/l in solution

// Styles dropdown list
var stylesUrl = "includes/db_profile_styles.php";
var stylesSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'category', type: 'string' },
		{ name: 'category_number', type: 'number' },
		{ name: 'style_letter', type: 'string' },
		{ name: 'style_guide', type: 'string' },
		{ name: 'type', type: 'string' },
		{ name: 'og_min', type: 'float' },
		{ name: 'og_max', type: 'float' },
		{ name: 'fg_min', type: 'float' },
		{ name: 'fg_max', type: 'float' },
		{ name: 'ibu_min', type: 'float' },
		{ name: 'ibu_max', type: 'float' },
		{ name: 'color_min', type: 'float' },
		{ name: 'color_max', type: 'float' },
		{ name: 'carb_min', type: 'float' },
		{ name: 'carb_max', type: 'float' },
		{ name: 'abv_min', type: 'float' },
		{ name: 'abv_max', type: 'float' },
		{ name: 'notes', type: 'string' },
		{ name: 'profile', type: 'string' },
		{ name: 'ingredients', type: 'string' },
		{ name: 'examples', type: 'string' }
	],
	url: stylesUrl,
	async: true
};
var styleslist = new $.jqx.dataAdapter(stylesSource);

// Equipemnt dropdown list
var equipmentUrl = "includes/db_inventory_equipments.php";
var equipmentSource = {
	datatype: "json",
	datafields: [
		{ name: 'name', type: 'string' },
		{ name: 'boil_size', type: 'float' },
		{ name: 'batch_size', type: 'float' },
		{ name: 'tun_volume', type: 'float' },
		{ name: 'tun_weight', type: 'float' },
		{ name: 'tun_specific_heat', type: 'float' },
		{ name: 'tun_material', type: 'string' },
		{ name: 'tun_height', type: 'float' },
		{ name: 'top_up_water', type: 'float' },
		{ name: 'trub_chiller_loss', type: 'float' },
		{ name: 'evap_rate', type: 'float' },
		{ name: 'boil_time', type: 'float' },
		{ name: 'calc_boil_volume', type: 'bool' },
		{ name: 'top_up_kettle', type: 'float' },
		{ name: 'hop_utilization', type: 'float' },
		{ name: 'notes', type: 'string' },
		{ name: 'lauter_volume', type: 'float' },
		{ name: 'lauter_height', type: 'float' },
		{ name: 'lauter_deadspace', type: 'float' },
		{ name: 'kettle_volume', type: 'float' },
		{ name: 'kettle_height', type: 'float' },
		{ name: 'mash_volume', type: 'float' },
		{ name: 'mash_max', type: 'float' },
		{ name: 'efficiency', type: 'float' }
	],
	url: equipmentUrl,
	async: true
};
var equipmentlist = new $.jqx.dataAdapter(equipmentSource);

// dropdownlist datasource from inventory_fermentables
var fermentableInvSource = {
	datatype: "json",
        datafields: [
                { name: 'record', type: 'number' },
                { name: 'name', type: 'string' },
                { name: 'type', type: 'string' },
                { name: 'yield', type: 'float' },
                { name: 'color', type: 'float' },
                { name: 'add_after_boil', type: 'bool' },
                { name: 'origin', type: 'string' },
                { name: 'supplier', type: 'string' },
                { name: 'coarse_fine_diff', type: 'float' },
                { name: 'moisture', type: 'float' },
                { name: 'diastatic_power', type: 'float' },
                { name: 'protein', type: 'float' },
                { name: 'max_in_batch', type: 'float' },
                { name: 'recommend_mash', type: 'bool' },
                { name: 'graintype', type: 'string' },
                { name: 'di_ph', type: 'float' },
                { name: 'inventory', type: 'float' },
        	{ name: 'cost', type: 'float' }
        ],
        url: "getfermentablesources.php",
        async: true
};
var fermentableinstock = false;
var fermentablelist = new $.jqx.dataAdapter(fermentableInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || ! fermentableinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_hops
var hopInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'origin', type: 'string' },
		{ name: 'type', type: 'string' },
		{ name: 'alpha', type: 'float' },
		{ name: 'beta', type: 'float' },
		{ name: 'humulene', type: 'float' },
		{ name: 'caryophyllene', type: 'float' },
		{ name: 'cohumulone', type: 'float' },
		{ name: 'myrcene', type: 'float' },
		{ name: 'hsi', type: 'float' },
		{ name: 'useat', type: 'string' },
		{ name: 'form', type: 'string' },
		{ name: 'total_oil', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "gethopsources.php",
	async: true
};
var hopinstock = false;
var hoplist = new $.jqx.dataAdapter(hopInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || ! hopinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_miscs
var miscInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'type', type: 'string' },
		{ name: 'use_use', type: 'string' },
		{ name: 'amount_is_weight', type: 'bool' },
		{ name: 'time', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "getmiscsources.php",
	async: true
};
var miscinstock = false;
var misclist = new $.jqx.dataAdapter(miscInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
		var row = records[i];
			if (row.inventory || ! miscinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_yeasts
var yeastInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'type', type: 'string' },
		{ name: 'form', type: 'string' },
		{ name: 'laboratory', type: 'string' },
		{ name: 'product_id', type: 'string' },
		{ name: 'min_temperature', type: 'float' },
		{ name: 'max_temperature', type: 'float' },
		{ name: 'attenuation', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "getyeastsources.php",
	async: true
};
var yeastinstock = false;
var yeastlist = new $.jqx.dataAdapter(yeastInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || ! yeastinstock)
				data.push(row);
		}
		return data;
	},
	loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from inventory_waters
var waterInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'unlimited_stock', type: 'bool' },
		{ name: 'calcium', type: 'float' },
		{ name: 'sulfate', type: 'float' },
		{ name: 'chloride', type: 'float' },
		{ name: 'sodium', type: 'float' },
		{ name: 'magnesium', type: 'float' },
		{ name: 'ph', type: 'float' },
		{ name: 'total_alkalinity', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' },
	],
	url: "getwatersources.php",
	async: true
};
var waterinstock = false;
var waterlist = new $.jqx.dataAdapter(waterInvSource, {
	beforeLoadComplete: function (records) {
		var data = new Array();
		for (var i = 0; i < records.length; i++) {
			var row = records[i];
			if (row.inventory || row.unlimited_stock || ! waterinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		$('#err').text(status + ' ' + error);
	},
});

// dropdownlist datasource from profile_water
var waterProfileSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'calcium', type: 'float' },
		{ name: 'bicarbonate', type: 'float' },
		{ name: 'sulfate', type: 'float' },
		{ name: 'chloride', type: 'float' },
		{ name: 'sodium', type: 'float' },
		{ name: 'magnesium', type: 'float' },
		{ name: 'ph', type: 'float' },
		{ name: 'total_alkalinity', type: 'float' },
	],
	url: "includes/db_profile_water.php",
	async: true
};
var waterprofiles = new $.jqx.dataAdapter(waterProfileSource);

// dropdownlist datasource from profile_mash
var mashInvSource = {
	datatype: "json",
	datafields: [
		{ name: 'record', type: 'number' },
		{ name: 'name', type: 'string' },
		{ name: 'steps', type: 'array' }
	],
	url: "include/db_profile_mash.php",
	async: true
};
var mashlist = new $.jqx.dataAdapter(mashInvSource);



function getLocalization() {
	var localizationobj = {};
	localizationobj.pagerGoToPageString = "Gehe zu:";
	localizationobj.pagerShowRowsString = "Zeige Zeile:";
	localizationobj.pagerRangeString = " von ";
	localizationobj.pagerNextButtonString = "voriger";
	localizationobj.pagerFirstButtonString = "first";
	localizationobj.pagerLastButtonString = "last";
	localizationobj.pagerPreviousButtonString = "nächster";
	localizationobj.sortAscendingString = "Sortiere aufsteigend";
	localizationobj.sortDescendingString = "Sortiere absteigend";
	localizationobj.sortRemoveString = "Entferne Sortierung";
	localizationobj.firstDay = 1;
	localizationobj.percentSymbol = "%";
	localizationobj.currencySymbol = "€";
	localizationobj.currencySymbolPosition = "after";
	localizationobj.decimalSeparator = ",";
	localizationobj.thousandsSeparator = ".";
	var days = {
		// full day names
		names: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
		// abbreviated day names
		namesAbbr: ["Sonn", "Mon", "Dien", "Mitt", "Donn", "Fre", "Sams"],
		// shortest day names
		namesShort: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"]
	};
	localizationobj.days = days;
	var months = {
		// full month names (13 months for lunar calendards -- 13th month should be "" if not lunar)
		names: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", ""],
		// abbreviated month names
		namesAbbr: ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dez", ""]
	};
	var patterns = {
		d: "dd.MM.yyyy",
		D: "dddd, d. MMMM yyyy",
		t: "HH:mm",
		T: "HH:mm:ss",
		f: "dddd, d. MMMM yyyy HH:mm",
		F: "dddd, d. MMMM yyyy HH:mm:ss",
		M: "dd MMMM",
		Y: "MMMM yyyy"
	}
	localizationobj.patterns = patterns;
	localizationobj.months = months;
	return localizationobj;
}



$(document).ready(function () {

	$("#jqxMenu").jqxMenu({
		width: 1280,
		height: '30px',
		autoOpen: false,
		clickToOpen: true,
		theme: theme
	});
	$("#jqxWidget").css('visibility', 'visible');
});



function ebc_to_srm(ebc) {
	var srm = -1.32303E-12 * Math.pow(ebc, 4) - 0.00000000291515 * Math.pow(ebc, 3) + 0.00000818515 * Math.pow(ebc, 2) + 0.372038 * ebc + 0.596351;
	if ((ebc < 0) || (srm < 0))
		console.log("ebc_to_srm("+ebc+") = "+srm);
	return srm
}



function srm_to_ebc(srm)
{
	var ebc = Math.round(0.000000000176506 * Math.pow(srm, 4) + 0.000000154529 * Math.pow(srm, 3) - 0.000159428 * Math.pow(srm, 2) + 2.68837 * srm - 1.6004);
	if ((ebc < 0) || (srm < 0))
		console.log("srm_to_ebc("+srm+") = "+ebc);
	return ebc;
}



/*
 * Alcohol By Volume
 */
function abvol(og, fg) {

	if ((4.749804 - fg) != 0)
		return 486.8693 * (og - fg) / (4.749804 - fg);
	return 0;
}



/*
 * Kleurwerking naar SRM
 */
function kw_to_srm(colormethod, c) {

	if (colormethod == "Morey")
		return 1.4922 * Math.pow(c, 0.6859);
	if (colormethod == "Mosher")
		return 0.3 * c + 4.7;
	if (colormethod == "Daniels")
		return 0.2 * c + 8.4;
}



function kw_to_ebc(colormethod, c) {
	return srm_to_ebc(kw_to_srm(colormethod, c));
}



/*
 * Berekeningen uit https://www.hobbybrouwen.nl/forum/index.php/topic,6079.msg69464.html#msg69464
 */
function toIBU(Use, Form, SG, Volume, Amount, Boiltime, Alpha, Method)
{
	var gravity = parseFloat(SG);
	var liters  = parseFloat(Volume);
	var alpha   = parseFloat(Alpha)/100;
	var mass    = parseFloat(Amount) * 1000;
	var time    = parseFloat(Boiltime);
	var fmoment = 1.0;
	var pfactor = 1.0;
	var ibu     = 0;

	if ((Use == "Dry Hop") || (Use == "Dry hop") || (Use == "Whirlpool") || (Use == "Aroma")) {
		fmoment = 0.0;
	} else if (Use == "Mash") {
		fmoment += my_factor_mashhop / 100;		// Brouwhulp
	} else if ((Use == "First Wort") || (Use == "First wort"))  {
		fmoment += my_factor_fwh  / 100;		// Brouwhulp, Louis, Ozzie
	}

	if (Form == "Pellet") {
		pfactor += my_factor_pellet / 100;
	}
	if (Form == "Plug" ) {
		pfactor += my_factor_plug / 100;
	}

	if (Method == "Tinseth") {
		/* http://realbeer.com/hops/research.html */
		var AddedAlphaAcids = (alpha * mass * 1000) / liters;
		var Bigness_factor = 1.65 * Math.pow( 0.000125, gravity - 1);
		var BoilTime_factor = ((1 - Math.exp(-0.04 * time)) / 4.15);
		var utiisation = Bigness_factor * BoilTime_factor;
		ibu = Math.round(utiisation * AddedAlphaAcids * fmoment * pfactor * 10) / 10.0;
	}
	if (Method == "Daniels") {
		var boilfactor;
		var sgfactor;
		if (Form == "Leaf")
			boilfactor = -(0.0041*time*time)+(0.6162*time)+1.5779;
		else
			boilfactor = -(0.0051*time*time)+(0.7835*time)+1.9348;
		if (gravity < 1050)
			sgfactor = 0;
		else
			sgfactor = (gravity - 1050) / 200;
		ibu = Math.round(fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))) * 10) / 10;
	}
	if (Method == "Rager") {
		var boilfactor;
		var sgfactor;
		boilfactor = fmoment * 18.11 + 13.86 * Math.tanh((time * 31.32) / 18.27);
		if (gravity < 1050)
			sgfactor = 0;
		else
			sgfactor = (gravity - 1050) / 200;
		ibu = Math.round((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)) * 10) / 10;
	}

//	console.log("toIBU("+Use+","+Form+","+SG+","+Volume+","+Amount+","+Boiltime+","+Alpha+","+Method+"):"+ibu+" fm:"+fmoment+" pf:"+pfactor);
	return ibu;
}



function ebc_to_color(ebc) {
	return srm_to_color(ebc_to_srm(ebc));
}



function srm_to_color(srm) {

	var i = Math.round(srm * 10);
        if (i < 0) {
		i = 0;
	}
	if (i > 299) {
		i = 299;
	}

	/* Table copied from Brouwhulp/BrewBuddy */
	var R = [ 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, // 0
		  250, 250, 250, 250, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, // 2
		  234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 216, 215, // 4
		  214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 200, 199, 199, 198, 198, // 6
		  197, 197, 196, 196, 195, 195, 194, 194, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 8
		  192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 10
		  192, 192, 192, 192, 192, 192, 192, 192, 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, // 12
		  179, 178, 177, 175, 174, 172, 171, 169, 168, 167, 195, 164, 162, 161, 159, 158, 157, 155, 154, 152, // 14
		  151, 149, 148, 147, 145, 144, 142, 141, 139, 138, 137, 135, 134, 132, 131, 129, 128, 127, 125, 124, // 16
		  122, 121, 119, 118, 117, 115, 114, 112, 111, 109, 108, 107, 105, 104, 102, 101,  99,  98,  97,  95, // 18
		   94,  92,  91,  89,  88,  87,  85,  84,  82,  81,  79,  78,  77,  75,  74,  72,  71,  69,  68,  67, // 20
		   65,  64,  62,  61,  59,  58,  57,  55,  54,  52,  51,  49,  48,  47,  45,  44,  43,  41,  39,  38, // 22
		   37,  37,  36,  36,  35,  35,  34,  34,  33,  33,  32,  32,  31,  31,  30,  30,  29,  29,  28,  28, // 24
		   27,  27,  26,  26,  25,  25,  24,  24,  23,  23,  22,  22,  21,  21,  20,  20,  19,  19,  18,  18, // 26
		   17,  17,  16,  16,  15,  15,  14,  14,  13,  13,  12,  12,  11,  11,  10,  10,   9,   9,   8,   8 ];

	var G = [ 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
		  250, 250, 250, 250, 250, 250, 249, 248, 247, 246, 245, 244, 242, 240, 238, 236, 234, 232, 230, 228,
		  226, 224, 222, 220, 218, 216, 214, 212, 210, 208, 206, 204, 202, 200, 198, 196, 194, 192, 190, 188,
		  186, 184, 182, 180, 178, 176, 174, 172, 170, 168, 166, 164, 162, 160, 158, 156, 154, 152, 150, 148,
		  146, 144, 142, 141, 140, 139, 139, 138, 137, 136, 136, 135, 134, 133, 133, 132, 131, 130, 130, 129,
		  128, 127, 127, 126, 125, 124, 124, 123, 122, 121, 121, 120, 119, 118, 118, 117, 116, 115, 115, 114,
		  113, 112, 112, 111, 110, 109, 109, 108, 107, 106, 106, 105, 104, 103, 103, 102, 101, 100, 100,  99,
		   98,  97,  97,  96,  95,  94,  94,  93,  92,  91,  91,  90,  89,  88,  88,  87,  86,  85,  85,  84,
		   83,  82,  82,  81,  80,  79,  78,  77,  76,  75,  75,  74,  73,  72,  72,  71,  70,  69,  69,  68,
		   67,  66,  66,  65,  64,  63,  63,  62,  61,  60,  60,  59,  58,  57,  57,  56,  55,  54,  54,  53,
		   52,  51,  51,  50,  49,  48,  48,  47,  46,  45,  45,  44,  43,  42,  42,  41,  40,  39,  39,  38,
		   37,  36,  36,  35,  34,  33,  33,  32,  31,  30,  30,  29,  28,  27,  27,  26,  25,  24,  24,  23,
		   22,  22,  22,  21,  21,  21,  20,  20,  20,  19,  19,  19,  18,  18,  18,  17,  17,  17,  16,  16,
		   16,  15,  15,  15,  14,  14,  14,  13,  13,  13,  12,  12,  12,  11,  11,  11,  10,  10,  10,   9,
		    9,   9,   8,   8,   8,   7,   7,   7,   6,   6,   6,   5,   5,   5,   4,   4,   4,   3,   3,   3 ];

	var B = [ 210, 204, 199, 193, 188, 182, 177, 171, 166, 160, 155, 149, 144, 138, 133, 127, 122, 116, 111, 105,
		  100,  94,  89,  83,  78,  72,  67,  61,  56,  50,  45,  45,  45,  46,  46,  46,  46,  47,  47,  47,
		   47,  48,  48,  48,  48,  49,  49,  49,  49,  50,  50,  50,  50,  51,  51,  51,  51,  52,  52,  52,
		   52,  53,  53,  53,  53,  54,  54,  54,  54,  55,  55,  55,  55,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,  56,
		   56,  56,  56,  55,  55,  55,  55,  54,  54,  54,  54,  53,  53,  53,  53,  52,  52,  52,  52,  51,
		   51,  51,  51,  50,  50,  50,  50,  49,  49,  48,  47,  47,  46,  45,  45,  44,  43,  43,  42,  41,
		   41,  40,  39,  39,  38,  37,  37,  36,  35,  34,  33,  32,  31,  29,  28,  27,  26,  25,  24,  23,
		   21,  20,  19,  18,  17,  16,  15,  13,  12,  11,  10,   9,   8,   9,   9,  10,  10,  11,  11,  12,
		   12,  13,  13,  14,  14,  15,  15,  16,  16,  17,  17,  18,  18,  19,  19,  20,  20,  21,  21,  22,
		   21,  21,  21,  20,  20,  20,  19,  19,  19,  18,  18,  18,  17,  17,  17,  17,  16,  16,  15,  15,
		   15,  14,  14,  14,  13,  13,  13,  12,  12,  12,  11,  11,  11,  10,  10,  10,   9,   9,   9,   8,
		    8,   8,   7,   7,   7,   6,   6,   6,   5,   5,   5,   4,   4,   4,   3,   3,   3,   2,   2,   2 ];

	var color = R[i] * 65536 + G[i] * 256 + B[i];
	var result = color.toString(16).toUpperCase();
	if (result.length < 6) {
		result = '0' + result;
	}
	result = '#' + result;
	return result;
}



function sg_to_plato(sg) {
	if (sg > 0.5)
		return 259 - 259 / sg;
	return 0;
}



function plato_to_sg(plato) {
	if (plato < 259)
		return 259 / (259 - plato);
	return 1.000;
}



function estimate_sg(sugars, batch_size) {
	var plato = 100 * sugars / batch_size;

	var sg = plato_to_sg(plato);
	for (var i = 0; i < 20; i++) {
		if (sg > 0)
			plato = 100 * sugars / (batch_size * sg);
		sg = plato_to_sg(plato);
	}
//	console.log("estimate_sg(" + sugars + "," + batch_size + ") : " + sg);
	return sg;
}



function estimate_fg(percSugar, percCara, WGratio, TotTme, Temp, attenuation, og) {

	var	BD;

	console.log("estimate_fg("+percSugar+","+percCara+","+WGratio+","+TotTme+","+Temp+","+attenuation+","+og+")");

	if (percSugar > 40)
		percSugar = 0;
	if (percCara > 50)
		percCara = 0;
	if ((WGratio > 0) && (TotTme > 0)) {
		BD = WGratio;
		BD = max(2, min(5.5, BD));
		Temp = max(60, min(72, Temp));
	} else {
		BD = 3.5;
		Temp = 67;
		TotTme = 75;
	}
	if (attenuation < 30)
		attenuation = 77;

	var AttBeer = 0.00825 * attenuation + 0.00817 * BD - 0.00684 * Temp + 0.00026 * TotTme - 0.00356 * percCara + 0.00553 * percSugar + 0.547;
	var fg = Math.round((1 + (1 - AttBeer) * (og - 1)) * 1000) / 1000;
	console.log("fg:"+fg);
	return fg;
}


function CalcFrac(TpH, pK1, pK2, pK3) {

	var r1d = Math.pow(10, TpH - pK1);
	var r2d = Math.pow(10, TpH - pK2);
	var r3d = Math.pow(10, TpH - pK3);
	var dd = 1/(1 + r1d + r1d*r2d + r1d*r2d*r3d);
	var f1d = dd;
	var f2d = r1d*dd;
	var f3d = r1d*r2d*dd;
	var f4d = r1d*r2d*r3d*dd;
	return f2d + 2*f3d + 3*f4d;
}

mercurial