www/js/global.js

branch
stable
changeset 665
4d01937ae7af
parent 663
7de681f68506
child 671
4b54d6f79d25
--- a/www/js/global.js	Fri Oct 18 13:20:35 2019 +0200
+++ b/www/js/global.js	Fri May 01 16:37:31 2020 +0200
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * Copyright (C) 2014-2019
+ * Copyright (C) 2014-2020
  *
  * Michiel Broek <mbroek at mbse dot eu>
  *
@@ -24,18 +24,18 @@
 // 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' }
+ { 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,
@@ -45,13 +45,13 @@
 StageAdapter = new $.jqx.dataAdapter(StageSource),
 
 SplitData = [
- { id: 0, en: 'Not divided',     nl: 'Niet gesplitst',  ok: 100 },
- { id: 1, en: 'After mash',      nl: 'Na maischen',     ok: 2 },
- { id: 2, en: 'After boil',      nl: 'Na koken',        ok: 2 },
- { id: 3, en: 'After cooling',   nl: 'Na koelen',       ok: 2 },
- { id: 4, en: 'After primary',   nl: 'Na hoofdgisting', ok: 3 },
- { id: 5, en: 'After secondary', nl: 'Na nagisting',    ok: 4 },
- { id: 6, en: 'After tertiary',  nl: 'Na lageren',      ok: 5 }
+ { id: 0, en: 'Not divided', nl: 'Niet gesplitst', ok: 100 },
+ { id: 1, en: 'After mash', nl: 'Na maischen', ok: 2 },
+ { id: 2, en: 'After boil', nl: 'Na koken', ok: 2 },
+ { id: 3, en: 'After cooling', nl: 'Na koelen', ok: 2 },
+ { id: 4, en: 'After primary', nl: 'Na hoofdgisting', ok: 3 },
+ { id: 5, en: 'After secondary', nl: 'Na nagisting', ok: 4 },
+ { id: 6, en: 'After tertiary', nl: 'Na lageren', ok: 5 }
 ],
 SplitSource = {
  localdata: SplitData,
@@ -61,10 +61,10 @@
 SplitAdapter = new $.jqx.dataAdapter(SplitSource),
 
 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 }
+ { 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,
@@ -74,11 +74,11 @@
 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: 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' }
+ { id: 4, en: 'Adjunct', nl: 'Ongemout graan' }
 ],
 FermentableTypeSource = {
  localdata: FermentableTypeData,
@@ -88,13 +88,13 @@
 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: 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' }
+ { id: 5, en: 'Special', nl: 'Speciale mout' },
+ { id: 6, en: 'No malt', nl: 'Geen mout' }
 ],
 GrainTypeSource = {
  localdata: GrainTypeData,
@@ -120,8 +120,8 @@
 
 HopTypeData = [
  { id: 0, en: 'Bittering', nl: 'Bitterhop' },
- { id: 1, en: 'Aroma',     nl: 'Aromahop' },
- { id: 2, en: 'Both',      nl: 'Beide' }
+ { id: 1, en: 'Aroma', nl: 'Aromahop' },
+ { id: 2, en: 'Both', nl: 'Beide' }
 ],
 HopTypeSource = {
  localdata: HopTypeData,
@@ -131,11 +131,11 @@
 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: 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' }
+ { id: 4, en: 'Cryo', nl: 'Cryo' }
 ],
 HopFormSource = {
  localdata: HopFormData,
@@ -145,12 +145,12 @@
 HopFormAdapter = new $.jqx.dataAdapter(HopFormSource),
 
 HopUseData = [
- { id: 0, en: 'Mash',       nl: 'Maischhop' },
+ { id: 0, en: 'Mash', nl: 'Maischhop' },
  { id: 1, en: 'First wort', nl: 'First wort' },
- { 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' }
+ { 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,
@@ -160,17 +160,17 @@
 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: 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: 'Hybrid',    nl: 'Hybride' }
-// { id: 8, en: 'Mixed',     nl: 'Mixed' },
+ { id: 5, en: 'Brett', nl: 'Brett' },
+ { id: 6, en: 'Kveik', nl: 'Kveik' },
+ { id: 7, en: 'Hybrid', nl: 'Hybride' }
+// { id: 8, en: 'Mixed', nl: 'Mixed' },
 // { id: 9, en: 'Spontaneous', nl: 'Spontaan' },
-// { id: 10, en: 'Other',       nl: 'Overig' }
+// { id: 10, en: 'Other', nl: 'Overig' }
 ],
 YeastTypeSource = {
  localdata: YeastTypeData,
@@ -180,13 +180,13 @@
 YeastTypeAdapter = new $.jqx.dataAdapter(YeastTypeSource),
 
 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 },
- { id: 6, en: 'Dried',   nl: 'Gedroogd',     cells: 9000000000 }
+ { 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 },
+ { id: 6, en: 'Dried', nl: 'Gedroogd', cells: 9000000000 }  /* 9..18 billion MTF */
 ],
 YeastFormSource = {
  localdata: YeastFormData,
@@ -196,10 +196,10 @@
 YeastFormAdapter = new $.jqx.dataAdapter(YeastFormSource),
 
 YeastUseData = [
- { id: 0, en: 'Primary',   nl: 'Hoofdgisting' },
+ { id: 0, en: 'Primary', nl: 'Hoofdgisting' },
  { id: 1, en: 'Secondary', nl: 'Nagisting' },
- { id: 2, en: 'Tertiary',  nl: 'Lagering' },
- { id: 3, en: 'Bottle',    nl: 'Bottelen' }
+ { id: 2, en: 'Tertiary', nl: 'Lagering' },
+ { id: 3, en: 'Bottle', nl: 'Bottelen' }
 ],
 YeastUseSource = {
  localdata: YeastUseData,
@@ -209,9 +209,9 @@
 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: 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 = {
@@ -223,9 +223,9 @@
 
 ZymocideData = [
  { id: 0, en: 'None', nl: 'Niet' },
- { id: 1, en: 'K1',   nl: 'K1' },
- { id: 2, en: 'K2',   nl: 'K2' },
- { id: 3, en: 'K28',  nl: 'K28' },
+ { id: 1, en: 'K1', nl: 'K1' },
+ { id: 2, en: 'K2', nl: 'K2' },
+ { id: 3, en: 'K28', nl: 'K28' },
  { id: 4, en: 'Klus', nl: 'Klus' }
 ],
 ZymocideSource = {
@@ -237,8 +237,8 @@
 
 StarterTypeData = [
  { id: 0, en: 'Stirred', nl: 'Geroerd' },
- { id: 1, en: 'Shaken',  nl: 'Geschud' },
- { id: 2, en: 'Simple',  nl: 'Simpel' }
+ { id: 1, en: 'Shaken', nl: 'Geschud' },
+ { id: 2, en: 'Simple', nl: 'Simpel' }
 ],
 StarterTypeSource = {
  localdata: StarterTypeData,
@@ -248,13 +248,13 @@
 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: 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' }
+ { id: 6, en: 'Other', nl: 'Anders' }
 ],
 MiscTypeSource = {
  localdata: MiscTypeData,
@@ -264,12 +264,12 @@
 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: 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' }
+ { id: 5, en: 'Bottling', nl: 'Bottelen' }
 ],
 MiscUseSource = {
  localdata: MiscUseData,
@@ -280,8 +280,8 @@
 
 StyleTypeData = [
  { id: 0, en: 'Lager', nl: 'Ondergistend bier' },
- { id: 1, en: 'Ale',   nl: 'Bovengistend bier' },
- { id: 2, en: 'Mead',  nl: 'Mede' },
+ { 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' }
@@ -294,9 +294,9 @@
 StyleTypeAdapter = new $.jqx.dataAdapter(StyleTypeSource),
 
 MashStepTypeData = [
- { id: 0, en: 'Infusion',    nl: 'Infusie' },
+ { id: 0, en: 'Infusion', nl: 'Infusie' },
  { id: 1, en: 'Temperature', nl: 'Verwarming' },
- { id: 2, en: 'Decoction',   nl: 'Decoctie' }
+ { id: 2, en: 'Decoction', nl: 'Decoctie' }
 ],
 MashStepTypeSource = {
  localdata: MashStepTypeData,
@@ -306,9 +306,9 @@
 MashStepTypeAdapter = new $.jqx.dataAdapter(MashStepTypeSource),
 
 RecipeTypeData = [
- { id: 0, en: 'Extract',      nl: 'Extract' },
+ { id: 0, en: 'Extract', nl: 'Extract' },
  { id: 1, en: 'Partial Mash', nl: 'Deelmaisch' },
- { id: 2, en: 'All Grain',    nl: 'Mout' }
+ { id: 2, en: 'All Grain', nl: 'Mout' }
 ],
 RecipeTypeSource = {
  localdata: RecipeTypeData,
@@ -319,11 +319,8 @@
 
 IBUmethodData = [
  { id: 0, en: 'Tinseth', nl: 'Tinseth' },
- { id: 1, en: 'Rager',   nl: 'Rager' },
+ { 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,
@@ -333,11 +330,11 @@
 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: 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' }
+ { id: 4, en: 'Naudts', nl: 'Naudts' }
 ],
 ColorMethodSource = {
  localdata: ColorMethodData,
@@ -347,11 +344,11 @@
 ColorMethodAdapter = new $.jqx.dataAdapter(ColorMethodSource),
 
 CoolingTypeData = [
- { id: 0, en: '-',                   nl: '-' },
- { id: 1, en: 'Emersion chiller',    nl: 'Dompelkoeler' },
+ { 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' }
+ { id: 3, en: 'Au bain marie', nl: 'Au bain marie' },
+ { id: 4, en: 'Natural', nl: 'Laten afkoelen' }
 ],
 CoolingTypeSource = {
  localdata: CoolingTypeData,
@@ -361,8 +358,8 @@
 CoolingTypeAdapter = new $.jqx.dataAdapter(CoolingTypeSource),
 
 AerationTypeData = [
- { id: 0, en: 'None',   nl: 'Geen' },
- { id: 1, en: 'Air',    nl: 'Lucht' },
+ { id: 0, en: 'None', nl: 'Geen' },
+ { id: 1, en: 'Air', nl: 'Lucht' },
  { id: 2, en: 'Oxygen', nl: 'Zuurstof' }
 ],
 AerationTypeSource = {
@@ -373,10 +370,11 @@
 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' }
+ /* Note: AcidSG is for 100% use. AcidPrc is the default setting. */
+ { id: 0, en: 'Lactic', nl: 'Melkzuur', pK1: 3.86, pK2: 20, pK3: 20, MolWt: 90.08, AcidSG: 1238, AcidPrc: 80 },
+ { id: 1, en: 'Hydrochloric', nl: 'Zoutzuur', pK1: -7, pK2: 20, pK3: 20, MolWt: 36.46, AcidSG: 1497, AcidPrc: 28 },
+ { id: 2, en: 'Phosphoric', nl: 'Fosforzuur', pK1: 2.12, pK2: 7.20, pK3: 12.44, MolWt: 98.00, AcidSG: 1982, AcidPrc: 75 },
+ { id: 3, en: 'Sulfuric', nl: 'Zwavelzuur', pK1: -1, pK2: 1.92, pK3: 20, MolWt: 98.07, AcidSG: 1884, AcidPrc: 93 }
 ],
 AcidTypeSource = {
  localdata: AcidTypeData,
@@ -387,9 +385,9 @@
 
 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' }
+ { id: 1, en: 'Sodiumcarbonate', nl: 'Na2CO3' },
+ { id: 2, en: 'Calciumcarbonate', nl: 'CaCO3' },
+ { id: 3, en: 'Calciumhydroxide', nl: 'Ca(OH)2' }
 ],
 BaseTypeSource = {
  localdata: BaseTypeData,
@@ -401,7 +399,7 @@
 SpargeSourceData = [
  { id: 0, en: 'Source 1', nl: 'Bron 1' },
  { id: 1, en: 'Source 2', nl: 'Bron 2' },
- { id: 2, en: 'Mixed',    nl: 'Gemengd' }
+ { id: 2, en: 'Mixed', nl: 'Gemengd' }
 ],
 SpargeSourceSource = {
  localdata: SpargeSourceData,
@@ -418,17 +416,21 @@
 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 },
+Smal2dec = { inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 2, 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 },
+Show4dec = { inputMode: 'simple', theme: theme, width: 90, height: 23, readOnly: true, decimalDigits: 4 },
+Show5dec = { inputMode: 'simple', theme: theme, width: 90, height: 23, readOnly: true, decimalDigits: 5 },
   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 },
+Spin4dec = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, decimalDigits: 4, 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: 50, decimalDigits: 1, spinButtons: true },
+  YeastT = { inputMode: 'simple', theme: theme, width: 110, height: 23, min: 0, max: 45, 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 },
@@ -653,7 +655,14 @@
   { name: 'cells', type: 'float' },
   { name: 'inventory', type: 'float' },
   { name: 'cost', type: 'float' },
-  { name: 'tolerance', type: 'float' }
+  { name: 'tolerance', type: 'float' },
+  { name: 'sta1', type: 'int' },
+  { name: 'bacteria', type: 'int' },
+  { name: 'harvest_top', type: 'int' },
+  { name: 'harvest_time', type: 'int' },
+  { name: 'pitch_temperature', type: 'float' },
+  { name: 'pofpos', type: 'int' },
+  { name: 'zymocide', type: 'int' }
  ],
  url: 'getyeastsources.php'
 },
@@ -672,6 +681,7 @@
   console.log(status + ' ' + error);
  },
 }),
+yeastlablist = new $.jqx.dataAdapter(yeastInvSource, { autoBind: false, async: false, uniqueDataFields: ['laboratory'] }),
 
 // dropdownlist datasource from inventory_waters
 waterInvSource = {
@@ -738,38 +748,7 @@
  ],
  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;
-}
+mashlist = new $.jqx.dataAdapter(mashProfileSource);
 
 
 
@@ -872,7 +851,7 @@
 /*
  * Berekeningen uit https://www.hobbybrouwen.nl/forum/index.php/topic,6079.msg69464.html#msg69464
  */
-function toIBU(Use, Form, SG, Volume, Amount, Boiltime, Alpha, Method) {
+function toIBU(Use, Form, SG, Volume, Amount, Boiltime, Alpha, Method, Whirlpool9, Whirlpool7, Whirlpool6) {
 
  var gravity, liters, alpha, mass, time, fmoment = 1.0, pfactor = 1.0, ibu = 0, boilfactor, sgfactor,
      AddedAlphaAcids, Bigness_factor, BoilTime_factor, utiisation;
@@ -901,13 +880,39 @@
   pfactor += my_factor_cryohop / 100;
  }
 
+ // Ideas from Zymurgy March-April 2018. These are not exact formulas!
+ whirlibus = 0;
+ if (Use == 3 || Use == 4) { // Flameout or any whirlpool
+  if (Whirlpool9) {
+   // 20 mg/l/50 min
+   whirlibus += (alpha * mass * 20) / liters * (Whirlpool9 / 50);
+   //console.log('Whirlpool9:' + alpha * mass * 20 + ' liter:' + liters + ' time:' + Whirlpool9 + ' ibu' + (alpha * mass * 20) / liters * (Whirlpool9 / 50));
+  } else {
+   if (Use == 3) // Flameout hops are 2 minutes in this range.
+    whirlibus += (alpha * mass * 20) / liters * (2 / 50);
+  }
+  if (Whirlpool7) {
+   // 6 mg/l/50 min
+   whirlibus += (alpha * mass * 6) / liters * (Whirlpool7 / 50);
+   //console.log('Whirlpool7:' + alpha * mass * 6 + ' liter:' + liters + ' time:' + Whirlpool7 + ' ibu' + (alpha * mass * 6) / liters * (Whirlpool7 / 50));
+  } else {
+   if (Use == 3) // Flameout hops are 4 minutes in this range.
+    whirlibus += (alpha * mass * 6) / liters * (4 / 50);
+  }
+  if (Whirlpool6) {
+   // 2 mg/l/50 min
+   whirlibus += (alpha * mass * 2) / liters * (Whirlpool6 / 50);
+   //console.log('Whirlpool6:' + alpha * mass * 2 + ' liter:' + liters + ' time:' + Whirlpool6 + ' ibu' + (alpha * mass * 2) / liters * (Whirlpool6 / 50));
+  }
+ }
+
  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);
+  ibu = Round(utiisation * AddedAlphaAcids * fmoment * pfactor + whirlibus, 1);
  }
  if (Method == 2) { // Daniels
   if (Form == 2) // Leaf
@@ -918,7 +923,7 @@
    sgfactor = 0;
   else
    sgfactor = (gravity - 1050) / 200;
-  ibu = Round(fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))), 1);
+  ibu = Round(fmoment * ((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor))) + whirlibus, 1);
  }
  if (Method == 1) { // Rager
   boilfactor = fmoment * 18.11 + 13.86 * Math.tanh((time * 31.32) / 18.27);
@@ -926,10 +931,11 @@
    sgfactor = 0;
   else
    sgfactor = (gravity - 1050) / 200;
-  ibu = Round((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)), 1);
+  ibu = Round((mass * (alpha * 100) * boilfactor * 0.1) / (liters * (1 + sgfactor)) + whirlibus, 1);
  }
 
- //console.log("toIBU("+Use+","+Form+","+SG+","+Volume+","+Amount+","+Boiltime+","+Alpha+","+Method+"):"+ibu+" fm:"+fmoment+" pf:"+pfactor);
+// console.log('toIBU(' + Use + ',' + Form + ',' + SG + ',' + Volume + ',' + Amount + ',' + Boiltime + ',' +
+//             Alpha + ',' + Method + ',' + Whirlpool9 + ',' + Whirlpool7 + ',' + Whirlpool6 + '):' + ibu + ' fm:' + fmoment + ' pf:' + pfactor);
  return ibu;
 }
 
@@ -1013,13 +1019,23 @@
 
 
 function sg_to_plato(sg) {
- return ((135.997 * sg - 630.272) * sg + 1111.14) * sg - 616.868;
+// return ((135.997 * sg - 630.272) * sg + 1111.14) * sg - 616.868;
+ return -668.962 + (1262.45 * sg) - (776.43 * sg * sg) + (182.94 * sg * sg * sg);
 }
 
 
 
 function plato_to_sg(plato) {
- return 1 + (plato / (258.6 - ((plato / 258.2) * 227.1)));
+// return 1 + (plato / (258.6 - ((plato / 258.2) * 227.1)));
+ return 1.00001 + (0.0038661 * plato) + (1.3488e-5 * plato * plato) + (4.3074e-8 * plato * plato * plato);
+}
+
+
+
+function calc_svg(og, fg) {
+ var oe = sg_to_plato(og);
+ var ae = sg_to_plato(fg);
+ return (oe - ae) / oe * 100;
 }
 
 
@@ -1039,6 +1055,33 @@
 
 
 
+function brix_to_fg(OBrix, FBrix) {
+ // Brouwhulp, werkt zonder brix_correctie, waarom?
+ var FGbh = Round(1.0031 - 0.002318474 * OBrix - 0.000007775 * (OBrix * OBrix) - 0.000000034 * Math.pow(OBrix, 3) +
+            0.00574 * (FBrix) + 0.00003344 * (FBrix * FBrix) + 0.000000086 * Math.pow(FBrix, 3), 4);
+
+ // from http://seanterrill.com   FGoc = old cubix, FGnc = new cubic, FGnl = new linear
+ var OBc = OBrix / my_brix_correction;
+ var FBc = FBrix / my_brix_correction;
+
+ // Old Cubic, almost the same a BrouwHulp, different offset and with brix_correction.
+ var FGoc = Round(1.001843 - 0.002318474 * OBc - 0.000007775 * (OBc * OBc) - 0.000000034 * Math.pow(OBc, 3) +
+            0.00574 * (FBc) + 0.00003344 * (FBc * FBc) + 0.000000086 * Math.pow(FBc, 3), 4);
+
+ // New cubic. This looks the best to use.
+ var FGnc = Round(1 - 0.0044993 * (OBc) + 0.0117741 * (FBc) +
+            0.000275806 * (OBc * OBc) - 0.00127169 * (FBc * FBc) -
+            0.00000727999 * Math.pow(OBc, 3) + 0.0000632929 * Math.pow(FBc, 3), 4);
+
+ // New linear, results are pretty much too high and way off for heavy beers.
+ var FGnl = Round(1 - 0.000856829 * OBc + 0.00349412 * FBc, 4);
+
+ console.log('brix_to_fg(' + Round(OBrix, 2) + ', ' + FBrix + ') FGbh:' + FGbh + ' FGoc:' + FGoc + ' FGnc:' + FGnc + ' FGnl:' + FGnl);
+ return FGnc;
+}
+
+
+
 function estimate_sg(sugars, batch_size) {
 
  var plato, sg, i;
@@ -1124,3 +1167,16 @@
 }
 
 
+function kettle_cm(vol, kettle_vol, kettle_height) {
+ if ((vol > 0) && (kettle_vol > 0) && (vol <= kettle_vol))
+  return Round(100 * ((1 - vol / kettle_vol) * kettle_height), 1);
+ return 0;
+}
+
+
+function kettle_vol(cm, kettle_vol, kettle_height) {
+ if ((cm >= 0) && (kettle_vol > 0) && (cm <= (kettle_height * 100)))
+  return Round(((kettle_height - (cm / 100)) / kettle_height) * kettle_vol, 1);
+ return 0;
+}
+

mercurial