www/js/global.js

Sun, 24 Feb 2019 17:23:52 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 24 Feb 2019 17:23:52 +0100
changeset 286
124af734af68
parent 282
f765249d57d7
child 289
4082c41f45e9
permissions
-rw-r--r--

Version 0.1.0. Removed localization because it was messy, parts were localized and others not. In production and recipes ingredients not in stock are marked in red.

/*****************************************************************************
 * 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' }
//	{ id: 3, en: 'Leaf wet', nl: 'bellen nat' }
];
var HopFormSource = {
	localdata: HopFormData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
};
var HopFormAdapter = new $.jqx.dataAdapter(HopFormSource);

var HopUseData = [
	{ id: 0, en: 'Mash',       nl: 'maischhop' },
	{ id: 1, en: 'First wort', nl: 'first wort hop' },
	{ id: 2, en: 'Boil',       nl: 'koken' },
	{ id: 3, en: 'Aroma',      nl: 'vlamuit' },
	{ id: 4, en: 'Whirlpool',  nl: 'whirlpool' },
	{ id: 5, en: 'Dry hop',    nl: 'koudhop' }
];
var HopUseSource = {
	localdata: HopUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var HopUseAdapter = new $.jqx.dataAdapter(HopUseSource);

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' }, { name: 'cells' }]
};
var YeastFormAdapter = new $.jqx.dataAdapter(YeastFormSource);

var YeastUseData = [
	{ id: 0, en: 'Primary',   nl: 'Hoofdgisting' },
	{ id: 1, en: 'Secondary', nl: 'Nagisting' },
	{ id: 2, en: 'Tertiary',  nl: 'Lagering' },
	{ id: 3, en: 'Bottle',    nl: 'Bottelen' }
];
var YeastUseSource = {
	localdata: YeastUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'cells' }]
};
var YeastUseAdapter = new $.jqx.dataAdapter(YeastUseSource);

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: 'Stirred', nl: 'Geroerd' },
	{ id: 1, en: 'Shaken',  nl: 'Geschud' },
	{ id: 2, en: 'Simple',  nl: 'Simpel' }
];
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);

var StyleTypeData = [
	{ id: 0, en: 'Lager', nl: 'Ondergistend bier' },
	{ id: 1, en: 'Ale',   nl: 'Bovengistend bier' },
	{ id: 2, en: 'Mead',  nl: 'Mede' },
	{ id: 3, en: 'Wheat', nl: 'Tarwebier' },
	{ id: 4, en: 'Mixed', nl: 'Gemengd' },
	{ id: 5, en: 'Cider', nl: 'Cider' }
];
var StyleTypeSource = {
	localdata: StyleTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var StyleTypeAdapter = new $.jqx.dataAdapter(StyleTypeSource);

var MashStepTypeData = [
	{ id: 0, en: 'Infusion',    nl: 'Infusie' },
	{ id: 1, en: 'Temperature', nl: 'Directe verwarming' },
	{ id: 2, en: 'Decoction',   nl: 'Decoctie' }
];
var MashStepTypeSource = {
	localdata: MashStepTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var MashStepTypeAdapter = new $.jqx.dataAdapter(MashStepTypeSource);

var RecipeTypeData = [
	{ id: 0, en: 'Extract',      nl: 'Extract' },
	{ id: 1, en: 'Partial Mash', nl: 'Deelmaisch' },
	{ id: 2, en: 'All Grain',    nl: 'Mout' }
];
var RecipeTypeSource = {
	localdata: RecipeTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var RecipeTypeAdapter = new $.jqx.dataAdapter(RecipeTypeSource);

var IBUmethodData = [
	{ id: 0, en: 'Tinseth', nl: 'Tinseth' },
	{ id: 1, en: 'Rager',   nl: 'Rager' },
	{ id: 2, en: 'Daniels', nl: 'Daniels' }
//	{ id: 3, en: 'Garetz',  nl: 'Garetz' },	// Not yet supported.
//	{ id: 4, en: 'Mosher',  nl: 'Mosher' },
//	{ id: 5, en: 'Noonan',  nl: 'Noonan' }
];
var IBUmethodSource = {
	localdata: IBUmethodData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var IBUmethodAdapter = new $.jqx.dataAdapter(IBUmethodSource);

var ColorMethodData = [
	{ id: 0, en: 'Morey',   nl: 'Morey' },
	{ id: 1, en: 'Mosher',  nl: 'Mosher' },
	{ id: 2, en: 'Daniels', nl: 'Daniels' }
];
var ColorMethodSource = {
	localdata: ColorMethodData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var ColorMethodAdapter = new $.jqx.dataAdapter(ColorMethodSource);

var CoolingTypeData = [
	{ id: 0, en: '-',                   nl: '-' },
	{ id: 1, en: 'Emersion chiller',    nl: 'Dompelkoeler' },
	{ id: 2, en: 'Counterflow chiller', nl: 'Tegenstroomkoeler' },
	{ id: 3, en: 'Au bain marie',       nl: 'Au bain marie' },
	{ id: 4, en: 'Natural',             nl: 'Laten afkoelen' }
];
var CoolingTypeSource = {
	localdata: CoolingTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var CoolingTypeAdapter = new $.jqx.dataAdapter(CoolingTypeSource);

var AerationTypeData = [
	{ id: 0, en: 'None',   nl: 'Geen' },
	{ id: 1, en: 'Air',    nl: 'Lucht' },
	{ id: 2, en: 'Oxygen', nl: 'Zuurstof' }
];
var AerationTypeSource = {
	localdata: AerationTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
};
var AerationTypeAdapter = new $.jqx.dataAdapter(AerationTypeSource);

var PrimingSugarData = [
	{ id: 0, en: 'Saccharose',          nl: 'Kristalsuiker',    factor: 1 },
	{ id: 1, en: 'Glucose or dextrose', nl: 'Glucose/dextrose', factor: 1.16 },
	{ id: 2, en: 'Honey',               nl: 'Honing',           factor: 1.28 },
	{ id: 3, en: 'DME',                 nl: 'Moutextract',      factor: 1.74 },
	{ id: 4, en: 'Molassis',            nl: 'Melasse',          factor: 3.83 }
];
var PrimingSugarSource = {
	localdata: PrimingSugarData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'factor' }] 
};
var PrimingSugarAdapter = new $.jqx.dataAdapter(PrimingSugarSource);

var AcidTypeData = [
	{ id: 0, en: 'Lactic',       nl: 'Melkzuur' },
	{ id: 1, en: 'Hydrochloric', nl: 'Zoutzuur' },
	{ id: 2, en: 'Phosphoric',   nl: 'Fosforzuur' },
	{ id: 3, en: 'Sulfuric',     nl: 'Zwavelzuur' }
];
var AcidTypeSource = {
	localdata: AcidTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var AcidTypeAdapter = new $.jqx.dataAdapter(AcidTypeSource);

var BaseTypeData = [
	{ id: 0, en: 'Sodiumbicarbonate', nl: 'NaHCO3' },
	{ id: 1, en: 'Sodiumcarbonate',   nl: 'Na2CO3' },
	{ id: 2, en: 'Calciumcarbonate',  nl: 'CaCO3' },
	{ id: 3, en: 'Calciumhydroxide',  nl: 'Ca(OH)2' }
];
var BaseTypeSource = {
	localdata: BaseTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var BaseTypeAdapter = new $.jqx.dataAdapter(BaseTypeSource);

var SpargeSourceData = [
	{ id: 0, en: 'Source 1', nl: 'Bron 1' },
	{ id: 1, en: 'Source 2', nl: 'Bron 2' },
	{ id: 2, en: 'Mixed',    nl: 'Gemengd' }
];
var SpargeSourceSource = {
	localdata: SpargeSourceData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
};
var SpargeSourceAdapter = new $.jqx.dataAdapter(SpargeSourceSource);


// options for editors

var Show1wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 1, readOnly: true };
var Show2wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 2, readOnly: true };
var Show3wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 3, readOnly: true };
var Show0dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 0 };
var Show1dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 1 };
var Show2dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 2 };
var Show3dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 3 };
var SGopts   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0.990, max: 1.199, decimalDigits: 3, spinButtons: true };
var Spin1dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 1, spinButtons: true };
var Spin2dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 2, spinButtons: true };
var Spin3dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 3, spinButtons: true };
var SpinpH   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 1, max: 14, decimalDigits: 1, spinButtons: true };
var Spin2pH  = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 1, max: 14, decimalDigits: 2, spinButtons: true };
var YeastT   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true };
var PosInt   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 0, spinButtons: true };
var Perc1dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 100, decimalDigits: 1, spinButtons: true };
var Perc0    = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 100, decimalDigits: 0, spinButtons: true };
var Dateopts = {
	theme: theme, width: 150, height: 23, allowNullDate: true, todayString: 'Vandaag', clearString: 'Wissen', showFooter: true,
	formatString: 'yyyy-MM-dd', enableBrowserBoundsDetection: true
};
var DateTimeopts = {
	theme: theme, width: 230, height: 23, allowNullDate: true, todayString: 'Vandaag', clearString: 'Wissen', showFooter: true,
	formatString: 'yyyy-MM-dd HH:mm:ss', enableBrowserBoundsDetection: true, showTimeButton: 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: 'int' },
		{ 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
};
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: 'int' },
		{ 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: 'int' },
		{ 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
};
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: 'int' },
                { name: 'yield', type: 'float' },
                { name: 'color', type: 'float' },
                { name: 'add_after_boil', type: 'int' },
                { 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: 'dissolved_protein', type: 'float' },
                { name: 'max_in_batch', type: 'float' },
                { name: 'recommend_mash', type: 'int' },
                { name: 'graintype', type: 'int' },
                { name: 'di_ph', type: 'float' },
		{ name: 'acid_to_ph_57', type: 'float' },
                { name: 'inventory', type: 'float' },
        	{ name: 'cost', type: 'float' }
        ],
        url: "getfermentablesources.php"
};
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: 'int' },
		{ 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: 'int' },
		{ name: 'form', type: 'int' },
		{ name: 'total_oil', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "gethopsources.php"
};
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: 'int' },
		{ name: 'use_use', type: 'int' },
		{ name: 'amount_is_weight', type: 'int' },
		{ name: 'time', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "getmiscsources.php"
};
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: 'int' },
		{ name: 'form', type: 'int' },
		{ name: 'laboratory', type: 'string' },
		{ name: 'product_id', type: 'string' },
		{ name: 'min_temperature', type: 'float' },
		{ name: 'max_temperature', type: 'float' },
		{ name: 'flocculation', type: 'int' },
		{ name: 'attenuation', type: 'float' },
		{ name: 'cells', type: 'float' },
		{ name: 'inventory', type: 'float' },
		{ name: 'cost', type: 'float' }
	],
	url: "getyeastsources.php"
};
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: 'int' },
		{ 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"
};
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"
};
var waterprofiles = new $.jqx.dataAdapter(waterProfileSource);

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


/*
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 ((og - fg) < 0)
		return 0;

	return (76.08 * (og-fg) / (1.775-og)) * (fg / 0.794); // Daniels
// brouwhulp
	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 == 0)	// Morey
		return 1.4922 * Math.pow(c, 0.6859);
	if (colormethod == 1)	// Mosher
		return 0.3 * c + 4.7;
	if (colormethod == 2)	// 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 == 3) || (Use == 4) || (Use == 5)) {	// Aroma, Whirlpool or Dry hop.
		fmoment = 0.0;
	} else if (Use == 0) {				// Mash
		fmoment += my_factor_mashhop / 100;	// Brouwhulp
	} else if (Use == 1) {				// First wort
		fmoment += my_factor_fwh  / 100;	// Brouwhulp, Louis, Ozzie
	}

	if (Form == 0) {	// Pellet
		pfactor += my_factor_pellet / 100;
	}
	if (Form == 1 ) {	// Plug
		pfactor += my_factor_plug / 100;
	}
//	if (Form == 3) {	// Wet leaf
//		pfactor += 5.5;	// From https://github.com/chrisgilmerproj/brewday/blob/master/brew/constants.py
//	}

	if (Method == 0) {	// 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 == 2) {	// Daniels
		var boilfactor;
		var sgfactor;
		if (Form == 2)	// 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 == 1) {	// 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) {
	// http://www.brewersfriend.com/2012/10/31/on-the-relationship-between-plato-and-specific-gravity/
	return ((135.997 * sg - 630.272) * sg + 1111.14) * sg - 616.868;
}



function plato_to_sg(plato) {
	return 1 + (plato / (258.6 - ((plato / 258.2) * 227.1)));
}



function brix_to_sg(brix) {
	return plato_to_sg(brix / my_brix_correction);
}



function sg_to_brix(sg) {
	return sg_to_plato(sg) * my_brix_correction;
}



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;

	if (percSugar > 40)
		percSugar = 0;
	if (percCara > 50)
		percCara = 0;
	if ((WGratio > 0) && (TotTme > 0)) {
		BD = WGratio;
		if (BD < 2)
			BD = 2;
		if (BD > 5.5)
			BD = 5.5;
		if (Temp < 60)
			Temp = 60;
		if (Temp > 72)
			Temp = 72;
	} 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)) * 10000) / 10000;

	//console.log("estimate_fg("+percSugar+","+percCara+","+BD+","+TotTme+","+Temp+","+attenuation+","+og+") :"+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