www/js/global.js

Sat, 07 Sep 2019 10:47:24 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 07 Sep 2019 10:47:24 +0200
changeset 470
94a69f6b0f35
parent 465
dc3e14b976be
child 475
c34d71572023
permissions
-rw-r--r--

Delayed databind

/*****************************************************************************
 * 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" }
],
StageSource = {
	localdata: StageData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
StageAdapter = new $.jqx.dataAdapter(StageSource),

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: "Copper",          nl: "Koper",     sh: 0.092 }
],
MaterialSource = {
	localdata: MaterialData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'sh' }]
},
MaterialAdapter = new $.jqx.dataAdapter(MaterialSource),

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' }
],
FermentableTypeSource = {
	localdata: FermentableTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
FermentableTypeAdapter = new $.jqx.dataAdapter(FermentableTypeSource),

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: 'Geen mout' }
],
GrainTypeSource = {
	localdata: GrainTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
GrainTypeAdapter = new $.jqx.dataAdapter(GrainTypeSource),

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' },
	{ id: 5, en: 'Kegs', nl: 'Fust' }
],
AddedSource = {
	localdata: AddedData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
AddedAdapter = new $.jqx.dataAdapter(AddedSource),

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

HopFormData = [
	{ id: 0, en: 'Pellet',   nl: 'Pellets' },
	{ id: 1, en: 'Plug',     nl: 'Plugs' },
	{ id: 2, en: 'Leaf',     nl: 'Bloemen' },
	{ id: 3, en: 'Leaf wet', nl: 'Hop nat' },
	{ id: 4, en: 'Cryo',     nl: 'Cryo' }
],
HopFormSource = {
	localdata: HopFormData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
},
HopFormAdapter = new $.jqx.dataAdapter(HopFormSource),

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' }
],
HopUseSource = {
	localdata: HopUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
HopUseAdapter = new $.jqx.dataAdapter(HopUseSource),

YeastTypeData = [
	{ id: 0, en: 'Lager',     nl: 'Ondergist' },
	{ id: 1, en: 'Ale',       nl: 'Bovengist' },
	{ id: 2, en: 'Wheat',     nl: 'Tarwegist' },
	{ id: 3, en: 'Wine',      nl: 'Wijngist' },
	{ id: 4, en: 'Champagne', nl: 'Champagnegist' }
//	{ id: 5, en: 'Brett',     nl: 'Brett' },
//	{ id: 6, en: 'Kveik',     nl: 'Kveik' },
//	{ id: 7, en: 'Mixed',     nl: 'Mixed' },
//      { id: 8, en: 'Spontaneous', nl: 'Spontaan' },
//	{ id: 9, en: 'Other',       nl: 'Overig' }
],
YeastTypeSource = {
	localdata: YeastTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
YeastTypeAdapter = new $.jqx.dataAdapter(YeastTypeSource),

YeastFormData = [
	{ id: 0, en: 'Liquid',  nl: 'Vloeibaar',    cells: 100000000000 },
	{ id: 1, en: 'Dry',     nl: 'Korrel',       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 }
],
YeastFormSource = {
	localdata: YeastFormData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'cells' }]
},
YeastFormAdapter = new $.jqx.dataAdapter(YeastFormSource),

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' }
],
YeastUseSource = {
	localdata: YeastUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }, { name: 'cells' }]
},
YeastUseAdapter = new $.jqx.dataAdapter(YeastUseSource),

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' }
],
FlocculationSource = {
	localdata: FlocculationData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }] 
},
FlocculationAdapter = new $.jqx.dataAdapter(FlocculationSource),

StarterTypeData = [
	{ id: 0, en: 'Stirred', nl: 'Geroerd' },
	{ id: 1, en: 'Shaken',  nl: 'Geschud' },
	{ id: 2, en: 'Simple',  nl: 'Simpel' }
],
StarterTypeSource = {
	localdata: StarterTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
StarterTypeAdapter = new $.jqx.dataAdapter(StarterTypeSource),

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: 'Overig' }
],
MiscTypeSource = {
	localdata: MiscTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
MiscTypeAdapter = new $.jqx.dataAdapter(MiscTypeSource),

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' }
],
MiscUseSource = {
	localdata: MiscUseData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
MiscUseAdapter = new $.jqx.dataAdapter(MiscUseSource),

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' }
],
StyleTypeSource = {
	localdata: StyleTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
StyleTypeAdapter = new $.jqx.dataAdapter(StyleTypeSource),

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

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

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' }
],
IBUmethodSource = {
	localdata: IBUmethodData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
IBUmethodAdapter = new $.jqx.dataAdapter(IBUmethodSource),

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

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' }
],
CoolingTypeSource = {
	localdata: CoolingTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
CoolingTypeAdapter = new $.jqx.dataAdapter(CoolingTypeSource),

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

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' }
],
AcidTypeSource = {
	localdata: AcidTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
AcidTypeAdapter = new $.jqx.dataAdapter(AcidTypeSource),

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' }
],
BaseTypeSource = {
	localdata: BaseTypeData,
	datatype: "array",
	datafields: [{ name: 'id' }, { name: 'en' }, { name: 'nl' }]
},
BaseTypeAdapter = new $.jqx.dataAdapter(BaseTypeSource),

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


// options for editors

Show1wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 1, readOnly: true },
Show2wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 2, readOnly: true },
Show3wat = { inputMode: 'simple', theme: theme, width:  74, height: 23, decimalDigits: 3, readOnly: true },
Smal0dec = { inputMode: 'simple', theme: theme, width:  50, height: 23, decimalDigits: 0, readOnly: true },
Smal1dec = { inputMode: 'simple', theme: theme, width:  50, height: 23, decimalDigits: 1, readOnly: true },
Show0dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 0 },
Show1dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 1 },
Show2dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 2 },
Show3dec = { inputMode: 'simple', theme: theme, width:  90, height: 23, readOnly: true, decimalDigits: 3 },
SGopts   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0.990, max: 1.199, decimalDigits: 3, spinButtons: true },
Spin1dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 1, spinButtons: true },
Spin2dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 2, spinButtons: true },
Spin3dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 3, spinButtons: true },
SpinpH   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 1, max: 14, decimalDigits: 1, spinButtons: true },
Spin2pH  = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 1, max: 14, decimalDigits: 2, spinButtons: true },
YeastT   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 40, decimalDigits: 1, spinButtons: true },
PosInt   = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 0, spinButtons: true },
Perc1dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 100, decimalDigits: 1, spinButtons: true },
Perc0    = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 100, decimalDigits: 0, spinButtons: true },
Dateopts = {
	theme: theme, width: 150, height: 23, allowNullDate: true, todayString: 'Vandaag', clearString: 'Wissen', showFooter: true,
	formatString: 'yyyy-MM-dd', enableBrowserBoundsDetection: true
},
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
},


sugardensity = 1.611, //kg/l in solution

// Styles dropdown list
stylesUrl = "includes/db_profile_styles.php",
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
},
styleslist = new $.jqx.dataAdapter(stylesSource),

// Equipemnt dropdown list
equipmentUrl = "includes/db_inventory_equipments.php",
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
},
equipmentlist = new $.jqx.dataAdapter(equipmentSource),

// dropdownlist datasource from inventory_fermentables
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"
},
fermentableinstock = false,
fermentablelist = new $.jqx.dataAdapter(fermentableInvSource, {
	beforeLoadComplete: function (records) {
		var row, i, data = new Array();
		for (i = 0; i < records.length; i++) {
			row = records[i];
			if (row.inventory || ! fermentableinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		console.log(status + ' ' + error);
	},
}),
fermentablesugars = new $.jqx.dataAdapter(fermentableInvSource, {
	beforeLoadComplete: function (records) {
		var row, i, data = new Array();
		for (i = 0; i < records.length; i++) {
			row = records[i];
			if (row.type == 1 || row.type == 3)	// Sugars or dry extract
				data.push(row);
		}
		return data;
	},
	loadError: function(jqXHR, status, error) {
		console.log(status + ' ' + error);
	},
}),

// dropdownlist datasource from inventory_hops
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"
},
hopinstock = false,
hoplist = new $.jqx.dataAdapter(hopInvSource, {
	beforeLoadComplete: function (records) {
		var row, i, data = new Array();
		for (i = 0; i < records.length; i++) {
			row = records[i];
			if (row.inventory || ! hopinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		console.log(status + ' ' + error);
	},
}),

// dropdownlist datasource from inventory_miscs
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"
},
miscinstock = false,
misclist = new $.jqx.dataAdapter(miscInvSource, {
	beforeLoadComplete: function (records) {
		var row, i, data = new Array();
		for (i = 0; i < records.length; i++) {
		row = records[i];
			if (row.inventory || ! miscinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		console.log(status + ' ' + error);
	},
}),

// dropdownlist datasource from inventory_yeasts
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' },
		{ name: 'tolerance', type: 'float' }
	],
	url: "getyeastsources.php"
},
yeastinstock = false,
yeastlist = new $.jqx.dataAdapter(yeastInvSource, {
	beforeLoadComplete: function (records) {
		var row, i, data = new Array();
		for (i = 0; i < records.length; i++) {
			row = records[i];
			if (row.inventory || ! yeastinstock)
				data.push(row);
		}
		return data;
	},
	loadError: function(jqXHR, status, error) {
		console.log(status + ' ' + error);
	},
}),

// dropdownlist datasource from inventory_waters
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"
},
waterinstock = false,
waterlist = new $.jqx.dataAdapter(waterInvSource, {
	beforeLoadComplete: function (records) {
		var data, i, row;
		data = new Array();
		for (i = 0; i < records.length; i++) {
			row = records[i];
			if (row.inventory || row.unlimited_stock || ! waterinstock)
				data.push(row);
		}
		return data;
	},
        loadError: function(jqXHR, status, error) {
		console.log(status + ' ' + error);
	},
}),

// dropdownlist datasource from profile_water
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"
},
waterprofiles = new $.jqx.dataAdapter(waterProfileSource),

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



/*
 * From "Rekenen aan bier" by Hans Halberstadt.
 */
K1s = 0.384, K1a = -0.177, K1e = 0.241, K1g = 0.247, Ks  = 0.1415, Ka1 = 0.058, Ka2 = 0.078, Ke  = 0.174, Kg  = 0.109;

// =E2/E6+(E3/E6)*$B$24/$B$23+(E3/E6)*(E3/E6)*$B$25/$B$23+E4/E6*$B$26/$B$23+E5/E6*$B$27/$B$23
// For Brix
function A(sugar, volume, alc, eiwit, glycerol) {

	var vol, A;

	vol = volume * 1000;
	A = sugar/vol + (alc/vol)*Ka1/Ks + (alc/vol)*(alc/vol) * Ka2/Ks + eiwit/vol * Ke/Ks + glycerol/vol * Kg/Ks;
	console.log("A("+sugar+"."+volume+","+alc+","+eiwit+","+glycerol+"):"+A);
	return A;
}

// =E2/E6+(E3/E6)*$B$20/$B$19+E4/E6*$B$21/$B$19+E5/E6*$B$22/$B$19
// for Plato
function B(sugar, volume, alc, eiwit, glycerol) {

	var vol, B;

	vol = volume * 1000;
	B = sugar/vol + (alc/vol)*K1a/K1s + eiwit/vol*K1e/K1s + glycerol/vol*K1g/K1s;
	console.log("B("+sugar+"."+volume+","+alc+","+eiwit+","+glycerol+"):"+B);
        return B;
}



$(document).ready(function(){

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



function Round(n,d){

        for (var i=0,m=1; i<d; i++,m*=10);
        return Math.round(n*m)/m;
}



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(srm<0)
		srm=0;
	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)
		ebc=0;
	return ebc;
}



/* Return incremented color by the boil and yeast.
 * https://www.hobbybrouwen.nl/forum/index.php/topic,19020.msg281132.html#msg281132 */
function get_kt(ebc){

	var kt=1;
	if(ebc<3)
		kt=3.5;
	else if(ebc<6)
		kt=3;
	else if(ebc<8)
		kt=2.75;
	else if(ebc<10)
		kt=2.5;
	else if(ebc<20)
		kt=1.8;
	else if(ebc<30)
		kt=1.6;
	else if(ebc<60)
		kt=1.3;
	else if(ebc<100)
		kt=1.2;
	else if(ebc<300)
		kt=1.1;
	return kt;
}



function abvol(og,fg){

	if(((og-fg)<0)||(fg<0.9))
		return 0;
	var factor = og*3157*Math.pow(10,-5) + 9.716*Math.pow(10,-2);
	return (og*1000-fg*1000)*factor;
}



/* Kleurwerking naar SRM. Niet voor Halberstadt, Naudts */
function kw_to_srm(colormethod,c){
	if(colormethod==0)
		return 1.4922*Math.pow(c,0.6859);//Morey
	if(colormethod==1)
		return 0.3*c+4.7;//Mosher
	if(colormethod==2)
		return 0.2*c+8.4;//Daniels
	return 0;//Halberstadt,Naudts
}



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, liters, alpha, mass, time, fmoment=1.0, pfactor=1.0, ibu=0, boilfactor, sgfactor,
	    AddedAlphaAcids, Bigness_factor, BoilTime_factor, utiisation;

	gravity = parseFloat(SG);
	liters = parseFloat(Volume);
	alpha = parseFloat(Alpha)/100;
	mass = parseFloat(Amount)*1000;
	time = parseFloat(Boiltime);

	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;
	} else if (Form==1) {			// Plug
		pfactor+=my_factor_plug/100;
	} else if (Form==3) {			// Wet leaf
		pfactor+=my_factor_wethop/100;	// From https://github.com/chrisgilmerproj/brewday/blob/master/brew/constants.py
	} else if (Form==4) {			// Cryo hop
		pfactor+=my_factor_cryohop/100;
	}

	if(Method==0){// Tinseth
		/* http://realbeer.com/hops/research.html */
		AddedAlphaAcids=(alpha*mass*1000)/liters;
		Bigness_factor=1.65*Math.pow(0.000125,gravity-1);
		BoilTime_factor=((1-Math.exp(-0.04*time))/4.15);
		utiisation=Bigness_factor*BoilTime_factor;
		ibu=Round(utiisation*AddedAlphaAcids*fmoment*pfactor,1);
	}
	if(Method==2){// Daniels
		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 = Round(fmoment*((mass*(alpha*100)*boilfactor* 0.1)/(liters*(1+sgfactor))),1);
	}
	if(Method==1){// Rager
		boilfactor = fmoment*18.11 + 13.86*Math.tanh((time*31.32)/18.27);
		if (gravity < 1050)
			sgfactor=0;
		else
			sgfactor=(gravity-1050)/200;
		ibu = Round((mass*(alpha*100)*boilfactor*0.1)/(liters*(1+sgfactor)),1);
	}

	//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, R, G, B, color, result;

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

	/* Table copied from Brouwhulp/BrewBuddy */
	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];

	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];

	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];

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



function sg_to_plato(sg){
	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){
	if(my_brix_correction>0)
		return plato_to_sg(brix/my_brix_correction);
	else 
		return plato_to_sg(brix);
}



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



function estimate_sg(sugars,batch_size){

	var plato, sg, i;

	plato = 100*sugars / batch_size;
	sg = plato_to_sg(plato);
	for (i = 0; i < 20; i++) {
		if (sg > 0)
			plato = 100*sugars / (batch_size*sg);
		sg = plato_to_sg(plato);
	}
	return Round(sg,4);
}



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

	var BD, AttBeer, fg;

	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;

	// 0.00825 Attenuation factor yeast
	// 0.00817 Attenuation factor water/grain ration
	// -0.00684 Attenuation factor mash temperature
	// 0.00026 Attenuation factor total mash time  (at some places this is 0.0026 this is wrong!)
	// -0.00356 Attenuation factor percentage crystal malt
	// 0.00553 Attenuation factor percentage simple sugars
	// 0.547 Attenuation factor constant
	AttBeer = 0.00825*attenuation + 0.00817*BD - 0.00684*Temp + 0.00026*TotTme - 0.00356*percCara + 0.00553*percSugar + 0.547;
	fg = Round(1 + (1 - AttBeer) * (og - 1), 4);

	console.log("estimate_fg("+percSugar+","+percCara+","+BD+","+TotTme+","+Temp+","+attenuation+","+og+") AttBeer:"+AttBeer+" fg:"+fg);
	return fg;
}



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

	var r1d, r2d, r3d, dd, f2d, f3d, f4d;

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



function lintner_to_kolbach(lintner) {

	return (3.5 * lintner) - 16;
}


function kolbach_to_lintner(kolbach) {

	return (kolbach + 16) / 3.5;
}

mercurial