Renamed prod_edit to prod_view.

Sat, 06 Aug 2022 22:10:28 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Sat, 06 Aug 2022 22:10:28 +0200
changeset 832
2641860ad61d
parent 831
21fae4d2203e
child 833
bdef871e6db7

Renamed prod_edit to prod_view.

www/Makefile file | annotate | diff | comparison | revisions
www/js/prod_edit.js file | annotate | diff | comparison | revisions
www/js/prod_inprod.js file | annotate | diff | comparison | revisions
www/js/prod_view.js file | annotate | diff | comparison | revisions
www/prod_edit.php file | annotate | diff | comparison | revisions
www/prod_view.php file | annotate | diff | comparison | revisions
--- a/www/Makefile	Sat Aug 06 22:02:42 2022 +0200
+++ b/www/Makefile	Sat Aug 06 22:10:28 2022 +0200
@@ -10,7 +10,7 @@
 		  index.php \
 		  log_co2pressure.php log_fermentation.php log_ispindel.php \
 		  mon_brewer.php mon_co2meter.php mon_fermenter.php mon_ispindel.php mon_node.php \
-		  prod_edit.php prod_inprod.php rec_view.php rec_main.php version.php
+		  prod_view.php prod_inprod.php rec_view.php rec_main.php version.php
 SUB		= version.php.in images/* css/* jqwidgets/* jqwidgets/styles/* \
 		  jqwidgets/styles/images/* jqwidgets/globalization/* js/* \
 		  includes/* fpdf/* import/*
--- a/www/js/prod_edit.js	Sat Aug 06 22:02:42 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3308 +0,0 @@
-/*****************************************************************************
- * Copyright (C) 2018-2022
- *
- * Michiel Broek <mbroek at mbse dot eu>
- *
- * This file is part of BMS
- *
- * 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.
- *****************************************************************************/
-
-
-function block_fermentable(stage, added) {
- if (stage > 5 && added < 4) // After fermentation and added before packaging
-  return true;
- if (stage > 3 && added < 3) // After primary and added before sec/tert
-  return true;
- if (stage > 2 && added < 2) // After boil and added during mash or boil
-  return true;
- return false;
-}
-
-function block_hop(stage, useat)
-{
- if (stage > 2 && useat < 5)
-  return true;
- return false;
-}
-
-function block_misc(stage, use_use) {
- if (stage > 5 && use_use < 5)
-  return true;
- if (stage > 3 && use_use < 4)
-  return true;
- if (stage > 2 && use_use < 3)
-  return true;
- if (stage > 1 && use_use < 1)
-  return true;
- return false;
-}
-
-function block_yeast(stage, use) {
- if (stage > 3 && use < 1)
-  return true;
- if (stage > 4 && use < 2)
-  return true;
- if (stage > 5 && use < 3)
-  return true;
- if (stage > 6 && use < 4)
-  return true;
- return false;
-}
-
-
-$(document).ready(function() {
-
- var i,
- to_100 = false,      // Fermentables adjust to 100%
- preboil_sg = 0,
- aboil_sg = 0,
- est_mash_sg = 0,
- psugar = 0,          // Percentage real sugars
- pcara = 0,           // Percentage cara/crystal malts
- svg = 77,            // Default attenuation
- mashkg = 0,          // Malt in mash weight
- initcells = 0,       // Initial yeast cell count
-
- ok_fermentables = 1, // Fermentables are in stock
- ok_hops = 1,         // Hops are in stock
- ok_miscs = 1,        // Miscs are in stock
- ok_yeasts = 1,       // Yeasts are in stock
- ok_waters = 1,       // Waters are in stock
-
- data_loaded = 0;
- error_count = 0;
- k_cm = 0;
- k_vol = 0;
- k_what = 0;
-
- hop_flavour = 0,
- hop_aroma = 0,
- mash_infuse = 0,
- last_acid = '',
-
- MMCa = 40.048,
- MMMg = 24.305,
- MMNa = 22.98976928,
- MMCl = 35.453,
- MMSO4 = 96.0626,
- MMHCO3 = 61.01684,
- MMCaSO4 = 172.171,
- MMCaCl2 = 147.015,
- MMCaCO3 = 100.087,
- MMMgCl2 = 95.211,	/* Since 27-06-2021 */
- MMMgSO4 = 246.475,
- MMNaHCO3 = 84.007,
- MMNa2CO3 = 105.996,
- MMNaCl = 58.443,
- MMCaOH2 = 74.06268,
-
- fermentableRow = 0,
- fermentableData = {},
- fermentableInit = 1,
- hopRow = 0,
- hopData = {},
- miscRow = 0,
- miscData = {},
- yeastRow = 0,
- yeastData = {},
- mashRow = 0,
- mashData = {},
- Ka1 = 0.0000004445,
- Ka2 = 0.0000000000468,
- dataRecord = {},
- url = 'includes/db_product.php',
- MaltVolume = 0.87,    // l/kg 0.688 volgens internetbronnen, gemeten 0.874 l/kg, na enige tijd maischen 0,715 l/kg (A3 Otten).
- SpecificHeatWater = 1.0,
- SpecificHeatMalt = 0.399, //cal/g.°C
- SlakingHeat = 10.318, //cal/g.°C
-
- // Prepare the data
- source = {
-  datatype: 'json',
-  cache: false,
-  async: true,
-  datafields: [
-   // From prod_main
-   { name: 'record', type: 'number' },
-   { name: 'uuid', type: 'string' },
-   { name: 'name', type: 'string' },
-   { name: 'code', type: 'string' },
-   { name: 'birth', type: 'string' },
-   { name: 'stage', type: 'int' },
-   { name: 'notes', type: 'string' },
-   { name: 'log_brew', type: 'int' },
-   { name: 'log_fermentation', type: 'int' },
-   { name: 'log_ispindel', type: 'int' },
-   { name: 'log_co2pressure', type: 'int' },
-   { name: 'inventory_reduced', type: 'int' },
-   { name: 'locked', type: 'int' },
-   { name: 'eq_name', type: 'string' },
-   { name: 'eq_boil_size', type: 'float' },
-   { name: 'eq_batch_size', type: 'float' },
-   { name: 'eq_tun_volume', type: 'float' },
-   { name: 'eq_tun_weight', type: 'float' },
-   { name: 'eq_tun_specific_heat', type: 'float' },
-   { name: 'eq_tun_material', type: 'int' },
-   { name: 'eq_tun_height', type: 'float' },
-   { name: 'eq_top_up_water', type: 'float' },
-   { name: 'eq_trub_chiller_loss', type: 'float' },
-   { name: 'eq_evap_rate', type: 'float' },
-   { name: 'eq_boil_time', type: 'float' },
-   { name: 'eq_calc_boil_volume', type: 'int' },
-   { name: 'eq_top_up_kettle', type: 'float' },
-   { name: 'eq_hop_utilization', type: 'float' },
-   { name: 'eq_notes', type: 'string' },
-   { name: 'eq_lauter_volume', type: 'float' },
-   { name: 'eq_lauter_height', type: 'float' },
-   { name: 'eq_lauter_deadspace', type: 'float' },
-   { name: 'eq_kettle_volume', type: 'float' },
-   { name: 'eq_kettle_height', type: 'float' },
-   { name: 'eq_mash_volume', type: 'float' },
-   { name: 'eq_mash_max', type: 'float' },
-   { name: 'eq_efficiency', type: 'float' },
-   { name: 'brew_date_start', type: 'string' },
-   { name: 'brew_mash_ph', type: 'float' },
-   { name: 'brew_mash_sg', type: 'float' },
-   { name: 'brew_mash_efficiency', type: 'float' },
-   { name: 'brew_sparge_est', type: 'float' },
-   { name: 'brew_sparge_ph', type: 'float' },
-   { name: 'brew_preboil_volume', type: 'float' },
-   { name: 'brew_preboil_sg', type: 'float' },
-   { name: 'brew_preboil_ph', type: 'float' },
-   { name: 'brew_preboil_efficiency', type: 'float' },
-   { name: 'brew_aboil_volume', type: 'float' },
-   { name: 'brew_aboil_sg', type: 'float' },
-   { name: 'brew_aboil_ph', type: 'float' },
-   { name: 'brew_aboil_efficiency', type: 'float' },
-   { name: 'brew_cooling_method', type: 'int' },
-   { name: 'brew_cooling_time', type: 'float' },
-   { name: 'brew_cooling_to', type: 'float' },
-   { name: 'brew_whirlpool9', type: 'float' },
-   { name: 'brew_whirlpool7', type: 'float' },
-   { name: 'brew_whirlpool6', type: 'float' },
-   { name: 'brew_whirlpool2', type: 'float' },
-   { name: 'brew_fermenter_volume', type: 'float' },
-   { name: 'brew_fermenter_extrawater', type: 'float' },
-   { name: 'brew_fermenter_tcloss', type: 'float' },
-   { name: 'brew_aeration_time', type: 'float' },
-   { name: 'brew_aeration_speed', type: 'float' },
-   { name: 'brew_aeration_type', type: 'int' },
-   { name: 'brew_fermenter_sg', type: 'float' },
-   { name: 'brew_fermenter_ibu', type: 'float' },
-   { name: 'brew_fermenter_color', type: 'float' },
-   { name: 'brew_date_end', type: 'string' },
-   { name: 'og', type: 'float' },
-   { name: 'fg', type: 'float' },
-   { name: 'primary_start_temp', type: 'float' },
-   { name: 'primary_max_temp', type: 'float' },
-   { name: 'primary_end_temp', type: 'float' },
-   { name: 'primary_end_sg', type: 'float' },
-   { name: 'primary_end_date', type: 'string' },
-   { name: 'secondary_temp', type: 'float' },
-   { name: 'secondary_end_sg', type: 'float' },
-   { name: 'secondary_end_date', type: 'string' },
-   { name: 'tertiary_temp', type: 'float' },
-   { name: 'package_date', type: 'string' },
-   { name: 'package_volume', type: 'float' },
-   { name: 'package_infuse_amount', type: 'float' },
-   { name: 'package_infuse_abv', type: 'float' },
-   { name: 'package_infuse_notes', type: 'string' },
-   { name: 'package_abv', type: 'float' },
-   { name: 'package_ph', type: 'float' },
-   { name: 'bottle_amount', type: 'float' },
-   { name: 'bottle_carbonation', type: 'float' },
-   { name: 'bottle_priming_water', type: 'float' },
-   { name: 'bottle_priming_amount', type: 'float' },
-   { name: 'bottle_carbonation_temp', type: 'float' },
-   { name: 'keg_amount', type: 'float' },
-   { name: 'keg_carbonation', type: 'float' },
-   { name: 'keg_priming_water', type: 'float' },
-   { name: 'keg_priming_amount', type: 'float' },
-   { name: 'keg_carbonation_temp', type: 'float' },
-   { name: 'keg_forced_carb', type: 'int' },
-   { name: 'keg_pressure', type: 'float' },
-   { name: 'taste_notes', type: 'string' },
-   { name: 'taste_rate', type: 'float' },
-   { name: 'taste_date', type: 'string' },
-   { name: 'taste_color', type: 'string' },
-   { name: 'taste_transparency', type: 'string' },
-   { name: 'taste_head', type: 'string' },
-   { name: 'taste_aroma', type: 'string' },
-   { name: 'taste_taste', type: 'string' },
-   { name: 'taste_mouthfeel', type: 'string' },
-   { name: 'taste_aftertaste', type: 'string' },
-   { name: 'st_name', type: 'string' },
-   { name: 'st_letter', type: 'string' },
-   { name: 'st_guide', type: 'string' },
-   { name: 'st_category', type: 'string' },
-   { name: 'st_category_number', type: 'int' },
-   { name: 'st_type', type: 'int' },
-   { name: 'st_og_min', type: 'float' },
-   { name: 'st_og_max', type: 'float' },
-   { name: 'st_fg_min', type: 'float' },
-   { name: 'st_fg_max', type: 'float' },
-   { name: 'st_ibu_min', type: 'float' },
-   { name: 'st_ibu_max', type: 'float' },
-   { name: 'st_color_min', type: 'float' },
-   { name: 'st_color_max', type: 'float' },
-   { name: 'st_carb_min', type: 'float' },
-   { name: 'st_carb_max', type: 'float' },
-   { name: 'st_abv_min', type: 'float' },
-   { name: 'st_abv_max', type: 'float' },
-   { name: 'type', type: 'int' },
-   { name: 'batch_size', type: 'float' },
-   { name: 'boil_size', type: 'float' },
-   { name: 'boil_time', type: 'float' },
-   { name: 'efficiency', type: 'float' },
-   { name: 'est_og', type: 'float' },
-   { name: 'est_og3', type: 'float' },
-   { name: 'est_fg', type: 'float' },
-   { name: 'est_abv', type: 'float' },
-   { name: 'est_color', type: 'float' },
-   { name: 'color_method', type: 'int' },
-   { name: 'est_ibu', type: 'float' },
-   { name: 'ibu_method', type: 'int' },
-   { name: 'est_carb', type: 'float' },
-   { name: 'sparge_temp', type: 'float' },
-   { name: 'sparge_ph', type: 'float' },
-   { name: 'sparge_volume', type: 'float' },
-   { name: 'sparge_source', type: 'int' },
-   { name: 'sparge_acid_type', type: 'int' },
-   { name: 'sparge_acid_perc', type: 'float' },
-   { name: 'sparge_acid_amount', type: 'float' },
-   { name: 'mash_ph', type: 'float' },
-   { name: 'mash_name', type: 'string' },
-   { name: 'calc_acid', type: 'int' },
-   { name: 'w1_name', type: 'string' },
-   { name: 'w1_amount', type: 'float' },
-   { name: 'w1_calcium', type: 'float' },
-   { name: 'w1_sulfate', type: 'float' },
-   { name: 'w1_chloride', type: 'float' },
-   { name: 'w1_sodium', type: 'float' },
-   { name: 'w1_magnesium', type: 'float' },
-   { name: 'w1_total_alkalinity', type: 'float' },
-   { name: 'w1_ph', type: 'float' },
-   { name: 'w1_cost', type: 'float' },
-   { name: 'w2_name', type: 'string' },
-   { name: 'w2_amount', type: 'float' },
-   { name: 'w2_calcium', type: 'float' },
-   { name: 'w2_sulfate', type: 'float' },
-   { name: 'w2_chloride', type: 'float' },
-   { name: 'w2_sodium', type: 'float' },
-   { name: 'w2_magnesium', type: 'float' },
-   { name: 'w2_total_alkalinity', type: 'float' },
-   { name: 'w2_ph', type: 'float' },
-   { name: 'w2_cost', type: 'float' },
-   { name: 'wg_amount', type: 'float' },
-   { name: 'wg_calcium', type: 'float' },
-   { name: 'wg_sulfate', type: 'float' },
-   { name: 'wg_chloride', type: 'float' },
-   { name: 'wg_sodium', type: 'float' },
-   { name: 'wg_magnesium', type: 'float' },
-   { name: 'wg_total_alkalinity', type: 'float' },
-   { name: 'wg_ph', type: 'float' },
-   { name: 'wb_calcium', type: 'float' },
-   { name: 'wb_sulfate', type: 'float' },
-   { name: 'wb_chloride', type: 'float' },
-   { name: 'wb_sodium', type: 'float' },
-   { name: 'wb_magnesium', type: 'float' },
-   { name: 'wb_total_alkalinity', type: 'float' },
-   { name: 'wb_ph', type: 'float' },
-   { name: 'wa_acid_name', type: 'int' },
-   { name: 'wa_acid_perc', type: 'int' },
-   { name: 'wa_base_name', type: 'int' },
-   { name: 'starter_enable', type: 'int' },
-   { name: 'starter_type', type: 'int' },
-   { name: 'starter_sg', type: 'float' },
-   { name: 'starter_viability', type: 'int' },
-   { name: 'yeast_prod_date', type: 'string' },
-   { name: 'yeast_pitchrate', type: 'float' },
-   { name: 'prop1_type', type: 'int' },
-   { name: 'prop1_volume', type: 'float' },
-   { name: 'prop2_type', type: 'int' },
-   { name: 'prop2_volume', type: 'float' },
-   { name: 'prop3_type', type: 'int' },
-   { name: 'prop3_volume', type: 'float' },
-   { name: 'prop4_type', type: 'int' },
-   { name: 'prop4_volume', type: 'float' },
-   { name: 'divide_type', type: 'int' },
-   { name: 'divide_size', type: 'float' },
-   { name: 'divide_factor', type: 'float' },
-   { name: 'divide_parts', type: 'int' },
-   { name: 'divide_part', type: 'int' },
-   { name: 'fermentables', type: 'string' },
-   { name: 'hops', type: 'string' },
-   { name: 'miscs', type: 'string' },
-   { name: 'yeasts', type: 'string' },
-   { name: 'mashs', type: 'string' }
-  ],
-  id: 'record',
-  url: url + '?record=' + my_record
- },
-
- // Load data and select one record.
- dataAdapter = new $.jqx.dataAdapter(source, {
-  loadComplete: function() {
-   dataRecord = dataAdapter.records[0];
-   // Hidden record uuid
-   $('#name').val(dataRecord.name);
-   $('#code').val(dataRecord.code);
-   $('#birth').val(dataRecord.birth);
-   $('#stage').val(StageData[dataRecord.stage].nl);
-   $('#notes').val(dataRecord.notes);
-   $('#locked').val(dataRecord.locked);
-   $('#eq_name').val(dataRecord.eq_name);
-   $('#eq_notes').val(dataRecord.eq_notes);
-   $('#eq_boil_size').val(dataRecord.eq_boil_size);
-   $('#eq_batch_size').val(dataRecord.eq_batch_size);
-   $('#eq_tun_volume').val(dataRecord.eq_tun_volume);
-   $('#eq_top_up_water').val(dataRecord.eq_top_up_water);
-   $('#eq_trub_chiller_loss').val(dataRecord.eq_trub_chiller_loss);
-   $('#eq_evap_rate').val(dataRecord.eq_evap_rate);
-   $('#eq_boil_time').val(dataRecord.eq_boil_time);
-   $('#eq_top_up_kettle').val(dataRecord.eq_top_up_kettle);
-   $('#eq_hop_utilization').val(dataRecord.eq_hop_utilization);
-   $('#eq_lauter_volume').val(dataRecord.eq_lauter_volume);
-   $('#eq_lauter_deadspace').val(dataRecord.eq_lauter_deadspace);
-   $('#eq_kettle_volume').val(dataRecord.eq_kettle_volume);
-   $('#eq_mash_volume').val(dataRecord.eq_mash_volume);
-   $('#eq_mash_max').val(dataRecord.eq_mash_max);
-   $('#eq_efficiency').val(dataRecord.eq_efficiency);
-   // Brewdate
-   $('#brew_date_start').val(dataRecord.brew_date_start);
-   $('#brew_mash_ph').val(dataRecord.brew_mash_ph);
-   $('#brew_mash_sg').val(dataRecord.brew_mash_sg);
-   $('#brew_mash_efficiency').val(dataRecord.brew_mash_efficiency);
-   // Header Spoelen en filteren
-   $('#brew_sparge_temperature').val(dataRecord.sparge_temp);
-   $('#brew_sparge_volume').val(dataRecord.sparge_volume);
-   $('#brew_sparge_est').val(dataRecord.brew_sparge_est);
-   $('#brew_sparge_ph').val(dataRecord.brew_sparge_ph);
-   // Header Beluchten
-   $('#brew_aeration_type').val(AerationTypeData[dataRecord.brew_aeration_type].nl);
-   $('#brew_aeration_time').val(dataRecord.brew_aeration_time);
-   $('#brew_aeration_speed').val(dataRecord.brew_aeration_speed);
-
-   $('#brew_preboil_ph').val(dataRecord.brew_preboil_ph);
-   $('#brew_preboil_sg').val(dataRecord.brew_preboil_sg);
-   $('#brew_preboil_volume').val(dataRecord.brew_preboil_volume);
-   $('#brew_preboil_efficiency').val(dataRecord.brew_preboil_efficiency);
-   // Header Koelen en whirlpoolen
-   $('#brew_whirlpool9').val(dataRecord.brew_whirlpool9);
-   $('#brew_whirlpool7').val(dataRecord.brew_whirlpool7);
-   $('#brew_whirlpool6').val(dataRecord.brew_whirlpool6);
-   $('#brew_whirlpool2').val(dataRecord.brew_whirlpool2);
-   // Header Naar gistvat
-   $('#brew_fermenter_volume').val(dataRecord.brew_fermenter_volume);
-   $('#brew_fermenter_sg').val(dataRecord.brew_fermenter_sg);
-   $('#brew_fermenter_sg2').val(dataRecord.brew_fermenter_sg);
-   $('#brew_fermenter_ibu').val(dataRecord.brew_fermenter_ibu);
-   $('#brew_fermenter_color').val(dataRecord.brew_fermenter_color);
-   $('#brew_fermenter_extrawater').val(dataRecord.brew_fermenter_extrawater);
-   $('#brew_fermenter_tcloss').val(dataRecord.brew_fermenter_tcloss);
-
-   $('#brew_aboil_ph').val(dataRecord.brew_aboil_ph);
-   $('#brew_aboil_sg').val(dataRecord.brew_aboil_sg);
-   $('#brew_aboil_volume').val(dataRecord.brew_aboil_volume);
-   $('#brew_aboil_efficiency').val(dataRecord.brew_aboil_efficiency);
-   // Header Koelen en whirlpoolen
-   $('#brew_cooling_to').val(dataRecord.brew_cooling_to);
-   $('#brew_cooling_method').val(CoolingTypeData[dataRecord.brew_cooling_method].nl);
-   $('#brew_cooling_time').val(dataRecord.brew_cooling_time);
-   // Niks
-   $('#brew_date_end').val(dataRecord.brew_date_end);
-   $('#og').val(dataRecord.og);
-   $('#fg').val(dataRecord.fg);
-   $('#primary_start_temp').val(dataRecord.primary_start_temp);
-   $('#primary_max_temp').val(dataRecord.primary_max_temp);
-   $('#primary_end_temp').val(dataRecord.primary_end_temp);
-   $('#primary_end_sg').val(dataRecord.primary_end_sg);
-   $('#primary_end_date').val(dataRecord.primary_end_date);
-   $('#secondary_temp').val(dataRecord.secondary_temp);
-   $('#secondary_end_sg').val(dataRecord.secondary_end_sg);
-   $('#secondary_end_date').val(dataRecord.secondary_end_date);
-   $('#tertiary_temp').val(dataRecord.tertiary_temp);
-   $('#package_date').val(dataRecord.package_date);
-   $('#package_volume').val(dataRecord.package_volume);
-   $('#package_infuse_amount').val(dataRecord.package_infuse_amount);
-   $('#package_infuse_abv').val(dataRecord.package_infuse_abv);
-   $('#package_infuse_notes').val(dataRecord.package_infuse_notes);
-   $('#package_abv').val(dataRecord.package_abv);
-   $('#package_ph').val(dataRecord.package_ph);
-   $('#bottle_amount').val(dataRecord.bottle_amount);
-   $('#bottle_carbonation').val(dataRecord.bottle_carbonation);
-   $('#bottle_priming_water').val(dataRecord.bottle_priming_water);
-   $('#bottle_priming_amount').val(dataRecord.bottle_priming_amount);
-   $('#bottle_carbonation_temp').val(dataRecord.bottle_carbonation_temp);
-   $('#keg_amount').val(dataRecord.keg_amount);
-   $('#keg_carbonation').val(dataRecord.keg_carbonation);
-   $('#keg_priming_water').val(dataRecord.keg_priming_water);
-   $('#keg_priming_amount').val(dataRecord.keg_priming_amount);
-   $('#keg_carbonation_temp').val(dataRecord.keg_carbonation_temp);
-   $('#keg_forced_carb').val(dataRecord.keg_forced_carb);
-   $('#keg_pressure').val(dataRecord.keg_pressure);
-   $('#taste_notes').val(dataRecord.taste_notes);
-   $('#taste_rate').val(dataRecord.taste_rate);
-   $('#taste_date').val(dataRecord.taste_date);
-   $('#taste_color').val(dataRecord.taste_color);
-   $('#taste_transparency').val(dataRecord.taste_transparency);
-   $('#taste_head').val(dataRecord.taste_head);
-   $('#taste_aroma').val(dataRecord.taste_aroma);
-   $('#taste_taste').val(dataRecord.taste_taste);
-   $('#taste_mouthfeel').val(dataRecord.taste_mouthfeel);
-   $('#taste_aftertaste').val(dataRecord.taste_aftertaste);
-
-   // Recipe
-   $('#st_name').val(dataRecord.st_name);
-   $('#st_letter').val(dataRecord.st_letter);
-   $('#st_guide').val(dataRecord.st_guide);
-   $('#st_category').val(dataRecord.st_category);
-   $('#st_category_number').val(dataRecord.st_category_number);
-   $('#st_type').val(StyleTypeData[dataRecord.st_type].nl);
-   $('#st_og_min').val(dataRecord.st_og_min);
-   $('#st_og_max').val(dataRecord.st_og_max);
-   $('#st_fg_min').val(dataRecord.st_fg_min);
-   $('#st_fg_max').val(dataRecord.st_fg_max);
-   $('#st_abv_min').val(dataRecord.st_abv_min);
-   $('#st_abv_max').val(dataRecord.st_abv_max);
-   $('#st_color_min').val(dataRecord.st_color_min);
-   $('#st_color_max').val(dataRecord.st_color_max);
-   $('#st_ibu_min').val(dataRecord.st_ibu_min);
-   $('#st_ibu_max').val(dataRecord.st_ibu_max);
-   $('#st_carb_min').val(dataRecord.st_carb_min);
-   $('#st_carb_min2').val(dataRecord.st_carb_min);
-   $('#st_carb_max').val(dataRecord.st_carb_max);
-   $('#st_carb_max2').val(dataRecord.st_carb_max);
-   $('#type').val(RecipeTypeData[dataRecord.type].nl);
-   $('#batch_size').val(dataRecord.batch_size);
-   $('#est_a_vol').val(dataRecord.batch_size * 1.04);
-   $('#boil_size').val(dataRecord.boil_size);
-   $('#est_pre_vol').val(dataRecord.boil_size * 1.04);
-   $('#boil_time').val(dataRecord.boil_time);
-   $('#efficiency').val(dataRecord.efficiency);
-   $('#est_og').val(dataRecord.est_og);
-   $('#est_og2').val(dataRecord.est_og);
-   $('#est_og3').val(dataRecord.est_og3);
-   $('#est_fg').val(dataRecord.est_fg);
-   $('#est_fg2').val(dataRecord.est_fg);
-   $('#est_fg3').val(dataRecord.est_fg);
-   $('#est_color').val(dataRecord.est_color);
-   $('#est_color2').val(dataRecord.est_color);
-   $('#est_abv').val(dataRecord.est_abv);
-   $('#color_method').val(ColorMethodData[dataRecord.color_method].nl);
-   $('#est_ibu').val(dataRecord.est_ibu);
-   $('#est_ibu2').val(dataRecord.est_ibu);
-   $('#ibu_method').val(IBUmethodData[dataRecord.ibu_method].nl);
-   $('#est_carb').val(dataRecord.est_carb);
-   $('#mash_name').val(dataRecord.mash_name);
-   $('#mash_ph').val(dataRecord.mash_ph);
-   $('#sparge_temp').val(dataRecord.sparge_temp);
-   $('#sparge_ph').val(dataRecord.sparge_ph);
-   $('#sparge_volume').val(dataRecord.sparge_volume);
-   $('#sparge_source').val(dataRecord.sparge_source);
-   $('#sparge_acid_type').val(AcidTypeData[dataRecord.sparge_acid_type].nl);
-   $('#sparge_acid_perc').val(dataRecord.sparge_acid_perc);
-   $('#sparge_acid_amount').val(dataRecord.sparge_acid_amount * 1000);
-   $('#calc_acid').val(dataRecord.calc_acid);
-   $('#w1_name').val(dataRecord.w1_name);
-   $('#w1_amount').val(dataRecord.w1_amount);
-   $('#w1_calcium').val(dataRecord.w1_calcium);
-   $('#w1_sulfate').val(dataRecord.w1_sulfate);
-   $('#w1_chloride').val(dataRecord.w1_chloride);
-   $('#w1_sodium').val(dataRecord.w1_sodium);
-   $('#w1_magnesium').val(dataRecord.w1_magnesium);
-   $('#w1_total_alkalinity').val(dataRecord.w1_total_alkalinity);
-   $('#w1_bicarbonate').val(dataRecord.w1_total_alkalinity * 1.22);
-   $('#w1_ph').val(dataRecord.w1_ph);
-   $('#w1_cost').val(dataRecord.w1_cost);
-   $('#w2_name').val(dataRecord.w2_name);
-   $('#w2_amount').val(dataRecord.w2_amount);
-   $('#w2_calcium').val(dataRecord.w2_calcium);
-   $('#w2_sulfate').val(dataRecord.w2_sulfate);
-   $('#w2_chloride').val(dataRecord.w2_chloride);
-   $('#w2_sodium').val(dataRecord.w2_sodium);
-   $('#w2_magnesium').val(dataRecord.w2_magnesium);
-   $('#w2_total_alkalinity').val(dataRecord.w2_total_alkalinity);
-   $('#w2_bicarbonate').val(dataRecord.w2_total_alkalinity * 1.22);
-   $('#w2_ph').val(dataRecord.w2_ph);
-   $('#w2_cost').val(dataRecord.w2_cost);
-   $('#wg_amount').val(dataRecord.wg_amount);
-   $('#wg_calcium').val(dataRecord.wg_calcium);
-   $('#wg_sulfate').val(dataRecord.wg_sulfate);
-   $('#wg_chloride').val(dataRecord.wg_chloride);
-   $('#wg_sodium').val(dataRecord.wg_sodium);
-   $('#wg_magnesium').val(dataRecord.wg_magnesium);
-   $('#wg_total_alkalinity').val(dataRecord.wg_total_alkalinity);
-   $('#wg_ph').val(dataRecord.wg_ph);
-   $('#wb_calcium').val(dataRecord.wb_calcium);
-   $('#wb_sulfate').val(dataRecord.wb_sulfate);
-   $('#wb_chloride').val(dataRecord.wb_chloride);
-   $('#wb_sodium').val(dataRecord.wb_sodium);
-   $('#wb_magnesium').val(dataRecord.wb_magnesium);
-   $('#wb_total_alkalinity').val(dataRecord.wb_total_alkalinity);
-   $('#wb_ph').val(dataRecord.wb_ph);
-   $('#wa_acid_name').val(dataRecord.wa_acid_name);
-   $('#wa_acid_perc').val(dataRecord.wa_acid_perc);
-   $('#starter_type').val(StarterTypeData[dataRecord.starter_type].nl);
-   $('#starter_sg').val(dataRecord.starter_sg);
-   $('#starter_viability').val(dataRecord.starter_viability);
-   $('#yeast_prod_date').val(dataRecord.yeast_prod_date);
-   $('#yeast_pitchrate').val(dataRecord.yeast_pitchrate);
-   $('#prop1_type').val(StarterTypeData[dataRecord.prop1_type].nl);
-   $('#prop1_volume').val(dataRecord.prop1_volume);
-   $('#prop2_type').val(StarterTypeData[dataRecord.prop2_type].nl);
-   $('#prop2_volume').val(dataRecord.prop2_volume);
-   $('#prop3_type').val(StarterTypeData[dataRecord.prop3_type].nl);
-   $('#prop3_volume').val(dataRecord.prop3_volume);
-   $('#prop4_type').val(StarterTypeData[dataRecord.prop4_type].nl);
-   $('#prop4_volume').val(dataRecord.prop4_volume);
-   $('#divide_type').val(SplitData[dataRecord.divide_type].nl);
-   if (dataRecord.divide_type > 0)
-    $('#divide_batch').val((dataRecord.divide_part + 1) + ' van ' + (dataRecord.divide_parts + 1));
-   else
-    $('#divide_batch').val('n.v.t.');
-   // hidden divide_size
-   // hidden divide_factor
-   // hidden divide_parts
-   // hidden divide_part
-   editFermentable(dataRecord);
-   editHop(dataRecord);
-   editMisc(dataRecord);
-   editYeast(dataRecord);
-   editMash(dataRecord);
-   calcStage();
-   $('#jqxTabs').jqxTabs('select', 2);
-   data_loaded = 1;
-  },
-  loadError: function(jqXHR, status, error) {
-   console.log('main data load error: ' + status + ' ' + error);
-  }
- });
-
- // Inline fermentables editor
- var editFermentable = function(data) {
-  var fermentableSource = {
-   localdata: data.fermentables,
-   datafields: [
-    { name: 'f_name', type: 'string' },
-    { name: 'f_origin', type: 'string' },
-    { name: 'f_supplier', type: 'string' },
-    { name: 'f_amount', type: 'float' },
-    { name: 'f_cost', type: 'float' },
-    { name: 'f_type', type: 'int' },
-    { name: 'f_yield', type: 'float' },
-    { name: 'f_color', type: 'float' },
-    { name: 'f_coarse_fine_diff', type: 'float' },
-    { name: 'f_moisture', type: 'float' },
-    { name: 'f_diastatic_power', type: 'float' },
-    { name: 'f_protein', type: 'float' },
-    { name: 'f_max_in_batch', type: 'float' },
-    { name: 'f_graintype', type: 'int' },
-    { name: 'f_added', type: 'int' },
-    { name: 'f_dissolved_protein', type: 'float' },
-    { name: 'f_recommend_mash', type: 'int' },
-    { name: 'f_add_after_boil', type: 'int' },
-    { name: 'f_adjust_to_total_100', type: 'int' },
-    { name: 'f_percentage', type: 'float' },
-    { name: 'f_di_ph', type: 'float' },
-    { name: 'f_acid_to_ph_57', type: 'float' },
-    { name: 'f_inventory', type: 'float' },
-    { name: 'f_avail', type: 'int' }
-   ],
-  },
-  fermentableAdapter = new $.jqx.dataAdapter(fermentableSource);
-
-  $('#fermentableGrid').jqxGrid({
-   width: 1240,
-   height: 470,
-   source: fermentableAdapter,
-   theme: theme,
-   editable: false,
-   ready: function() { calcFermentables(); $('#jqxTabs').jqxTabs('next'); },
-   columns: [
-    { text: 'Vergistbaar ingredi&euml;nt', datafield: 'f_name' },
-    { text: 'Leverancier', datafield: 'f_supplier', width: 180 },
-    { text: 'Kleur', datafield: 'f_color', width: 90, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value, 'f0') + ' EBC</span>';
-     }
-    },
-    { text: 'Type', width: 100, datafield: 'f_type',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + FermentableTypeData[value].nl + '</span>';
-     }
-    },
-    { text: 'Moment', width: 110, datafield: 'f_added',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + AddedData[value].nl + '</span>';
-     }
-    },
-    { text: 'Maxinbatch', datafield: 'f_max_in_batch', hidden: true },
-    { text: 'Opbrengst', datafield: 'f_yield', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'p1' },
-    { text: 'Gewicht Kg', datafield: 'f_amount', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'f3' },
-    { text: 'Voorraad Kg', datafield: 'f_inventory', width: 110, align: 'right',
-     cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
-      var color = (value < rowdata.f_amount) ? '#ff4040':'#ffffff';
-      if (block_fermentable(dataRecord.inventory_reduced, rowdata.f_added) == false) {
-       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + fermentableAdapter.formatNumber(value, 'f3') + '</span>';
-      } else {
-       return '<span></span>';
-      }
-     }
-    },
-    { text: 'Procent', datafield: 'f_percentage', width: 90, align: 'right',
-     cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
-      if (rowdata.f_added >= 4)
-       return '<span></span>';
-      var color = (value > rowdata.f_max_in_batch) ? '#ff4040':'#ffffff';
-      return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + fermentableAdapter.formatNumber(value, 'p1') + '</span>';
-     }
-    },
-    { text: '100%', datafield: 'f_adjust_to_total_100', width: 70, align: 'center', cellsalign: 'center',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      if (value == 0)
-       return '<span></span>';
-      return '<span><img style="float:left; margin-left:25px; margin-top:4px;" src="images/dialog-ok-apply.png"></span>';
-     }
-    }
-   ]
-  });
- };
-
- // Inline hops editor
- var editHop = function(data) {
-  var hopSource = {
-   localdata: data.hops,
-   datafields: [
-    { name: 'h_name', type: 'string' },
-    { name: 'h_origin', type: 'string' },
-    { name: 'h_amount', type: 'float' },
-    { name: 'h_cost', type: 'float' },
-    { name: 'h_type', type: 'int' },
-    { name: 'h_form', type: 'int' },
-    { name: 'h_useat', type: 'int' },
-    { name: 'h_time', type: 'int' },
-    { name: 'h_alpha', type: 'float' },
-    { name: 'h_beta', type: 'float' },
-    { name: 'h_hsi', type: 'float' },
-    { name: 'h_humulene', type: 'float' },
-    { name: 'h_caryophyllene', type: 'float' },
-    { name: 'h_cohumulone', type: 'float' },
-    { name: 'h_myrcene', type: 'float' },
-    { name: 'h_total_oil', type: 'float' },
-    { name: 'h_inventory', type: 'float' },
-    { name: 'h_avail', type: 'int' },
-    { name: 'h_utilisation', type: 'float' },
-    { name: 'h_bu_factor', type: 'float' }
-   ],
-  },
-  hopAdapter = new $.jqx.dataAdapter(hopSource);
-
-  $('#hopGrid').jqxGrid({
-   width: 1240,
-   height: 560,
-   source: hopAdapter,
-   theme: theme,
-   editable: false,
-   ready: function() { $('#jqxTabs').jqxTabs('next'); },
-   columns: [
-    { text: 'Hop', datafield: 'h_name' },
-    { text: 'Origin', width: 180, datafield: 'h_origin' },
-    { text: 'Type', width: 90, datafield: 'h_type',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopTypeData[value].nl + '</span>';
-     }
-    },
-    { text: 'Vorm', width: 110, datafield: 'h_form',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopFormData[value].nl + '</span>';
-     }
-    },
-    { text: 'Alpha', datafield: 'h_alpha', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'p1' },
-    { text: 'Gebruik', width: 110, datafield: 'h_useat',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopUseData[value].nl + '</span>';
-     }
-    },
-    { text: 'Tijdsduur', datafield: 'h_time', width: 90, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var duration = '';
-      if ((rowdata.h_useat == 2) || (rowdata.h_useat == 4))   // Boil, Whirlpool
-       duration = dataAdapter.formatNumber(value, 'f0') + ' min.';
-      else if (rowdata.h_useat == 5)       // Dry hop
-       duration = dataAdapter.formatNumber(value / 1440, 'f0') + ' dagen';
-      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>';
-     }
-    },
-    { text: 'IBU', datafield: 'ibu', width: 80, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var ibu = toIBU(rowdata.h_useat, rowdata.h_form, preboil_sg, parseFloat(dataRecord.batch_size),
-                parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time), parseFloat(rowdata.h_alpha), dataRecord.ibu_method,
-                dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6);
-      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(ibu, 'f1') + '</span>';
-     }
-    },
-    { text: 'Gewicht', datafield: 'h_amount', width: 110, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var amount = dataAdapter.formatNumber(value, 'f1') + ' kg';
-      if (value < 1)
-       amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
-      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>';
-     }
-    },
-    { text: 'Voorraad', datafield: 'h_inventory', width: 110, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      if (block_hop(dataRecord.inventory_reduced, rowdata.h_useat) == false) {
-       var amount = dataAdapter.formatNumber(value, 'f1') + ' kg',
-       color = (value < rowdata.h_amount) ? '#ff4040':'#ffffff';
-       if (value < 1)
-        amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
-       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
-      } else {
-       return '<span></span>';
-      }
-     }
-    }
-   ]
-  });
- };
-
- // Inline miscs editor
- var editMisc = function(data) {
-  var miscSource = {
-   localdata: data.miscs,
-   datafields: [
-    { name: 'm_name', type: 'string' },
-    { name: 'm_amount', type: 'float' },
-    { name: 'm_cost', type: 'float' },
-    { name: 'm_type', type: 'int' },
-    { name: 'm_use_use', type: 'int' },
-    { name: 'm_time', type: 'float' },
-    { name: 'm_amount_is_weight', type: 'int' },
-    { name: 'm_inventory', type: 'float' },
-    { name: 'm_avail', type: 'int' }
-   ],
-  },
-  miscAdapter = new $.jqx.dataAdapter(miscSource, {
-   beforeLoadComplete: function(records) {
-    var row, i, data = new Array();
-    for (i = 0; i < records.length; i++) {
-     row = records[i];
-     data.push(row);
-     // Initial set water agent values.
-     if (row.m_use_use == 1) {  // Mash
-      switch (row.m_name) {
-       case 'CaCl2':
-        $('#wa_cacl2').val(row.m_amount * 1000);
-        break;
-       case 'CaSO4':
-        $('#wa_caso4').val(row.m_amount * 1000);
-        break;
-       case 'MgSO4':
-        $('#wa_mgso4').val(row.m_amount * 1000);
-        break;
-       case 'NaCl':
-        $('#wa_nacl').val(row.m_amount * 1000);
-        break;
-       case 'MgCl2':
-        $('#wa_mgcl2').val(row.m_amount * 1000);
-        break;
-       case 'NaHCO3':
-        $('#wa_nahco3').val(row.m_amount * 1000);
-        break;
-       case 'CaCO3':
-        $('#wa_caco3').val(row.m_amount * 1000);
-        break;
-       case 'Melkzuur':
-        $('#wa_acid_name').val(AcidTypeData[0].nl);
-        $('#wa_acid').val(row.m_amount * 1000);
-        $('#wa_acid_perc').val(AcidTypeData[0].AcidPrc);
-        last_acid = 'Melkzuur';
-        break;
-       case 'Zoutzuur':
-        $('#wa_acid_name').val(AcidTypeData[1].nl);
-        $('#wa_acid').val(row.m_amount * 1000);
-        $('#wa_acid_perc').val(AcidTypeData[1].AcidPrc);
-        last_acid = 'Zoutzuur';
-        break;
-       case 'Fosforzuur':
-        $('#wa_acid_name').val(AcidTypeData[2].nl);
-        $('#wa_acid').val(row.m_amount * 1000);
-        $('#wa_acid_perc').val(AcidTypeData[2].AcidPrc);
-        last_acid = 'Fosforzuur';
-        break;
-       case 'Zwavelzuur':
-        $('#wa_acid_name').val(AcidTypeData[3].nl);
-        $('#wa_acid').val(row.m_amount * 1000);
-        $('#wa_acid_perc').val(AcidTypeData[3].AcidPrc);
-        last_acid = 'Zwavelzuur';
-        break;
-      }
-     }
-     if (row.m_use_use == 6) {  // Sparge
-      switch (row.m_name) {
-       case 'CaCl2':
-        $('#ss_cacl2').val(row.m_amount * 1000);
-        break;
-       case 'CaSO4':
-        $('#ss_caso4').val(row.m_amount * 1000);
-        break;
-       case 'MgSO4':
-        $('#ss_mgso4').val(row.m_amount * 1000);
-        break;
-       case 'NaCl':
-        $('#ss_nacl').val(row.m_amount * 1000);
-        break;
-       case 'MgCl2':
-        $('#ss_mgcl2').val(row.m_amount * 1000);
-        break;
-      }
-     }
-    }
-    return data;
-   },
-   loadError: function(jqXHR, status, error) { console.log('miscs load error ' + status + ' ' + error); },
-  });
-  $('#miscGrid').jqxGrid({
-   width: 1240,
-   height: 575,
-   source: miscAdapter,
-   theme: theme,
-   editable: false,
-   ready: function() { $('#jqxTabs').jqxTabs('next'); },
-   columns: [
-    { text: 'Ingredient', datafield: 'm_name' },
-    { text: 'Type', width: 140, datafield: 'm_type',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + MiscTypeData[value].nl + '</span>';
-     }
-    },
-    { text: 'Gebruik', width: 140, datafield: 'm_use_use',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + MiscUseData[value].nl + '</span>';
-     }
-    },
-    { text: 'Tijd', datafield: 'm_time', width: 90, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var duration = '';
-      if (rowdata.m_use_use == 2) // Boil
-       duration = dataAdapter.formatNumber(value, 'f0') + ' min.';
-      else if ((rowdata.m_use_use == 3) || (rowdata.m_use_use == 4)) // Primary or Secondary
-       duration = dataAdapter.formatNumber(value / 1440, 'f0') + ' dagen';
-      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>';
-     }
-    },
-    { text: 'Hoeveel', datafield: 'm_amount', width: 110, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var vstr = rowdata.m_amount_is_weight ? 'gr' : 'ml';
-      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value * 1000, 'f2') + ' ' + vstr + '</span>';
-     }
-    },
-    { text: 'Voorraad', datafield: 'm_inventory', width: 110, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      if (block_misc(dataRecord.inventory_reduced, rowdata.m_use_use) == false) {
-       var vstr = rowdata.m_amount_is_weight ? 'gr' : 'ml',
-       color = (value < rowdata.m_amount) ? '#ff4040':'#ffffff',
-       amount = dataAdapter.formatNumber(value * 1000, 'f2') + ' ' + vstr;
-       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
-      } else {
-       return '<span></span>';
-      }
-     }
-    }
-   ]
-  });
- };
-
- // Inline yeasts editor
- var editYeast = function(data) {
-  var yeastSource = {
-   localdata: data.yeasts,
-   datafields: [
-    { name: 'y_name', type: 'string' },
-    { name: 'y_laboratory', type: 'string' },
-    { name: 'y_product_id', type: 'string' },
-    { name: 'y_amount', type: 'float' },
-    { name: 'y_cost', type: 'float' },
-    { name: 'y_type', type: 'int' },
-    { name: 'y_form', type: 'int' },
-    { name: 'y_flocculation', type: 'int' },
-    { name: 'y_min_temperature', type: 'float' },
-    { name: 'y_max_temperature', type: 'float' },
-    { name: 'y_attenuation', type: 'float' },
-    { name: 'y_use', type: 'int' },
-    { name: 'y_cells', type: 'float' },
-    { name: 'y_tolerance', type: 'float' },
-    { name: 'y_inventory', type: 'float' },
-    { name: 'y_sta1', type: 'int' },
-    { name: 'y_bacteria', type: 'int' },
-    { name: 'y_harvest_top', type: 'int' },
-    { name: 'y_harvest_time', type: 'int' },
-    { name: 'y_pitch_temperature', type: 'float' },
-    { name: 'y_pofpos', type: 'int' },
-    { name: 'y_zymocide', type: 'int' },
-    { name: 'y_gr_hl_lo', type: 'int' },
-    { name: 'y_sg_lo', type: 'float' },
-    { name: 'y_gr_hl_hi', type: 'int' },
-    { name: 'y_sg_hi', type: 'float' },
-    { name: 'y_avail', type: 'int' }
-   ],
-  },
-  yeastAdapter = new $.jqx.dataAdapter(yeastSource);
-
-  $('#yeastGrid').jqxGrid({
-   width: 1240,
-   height: 325,
-   source: yeastAdapter,
-   theme: theme,
-   editable: false,
-   ready: function() { $('#jqxTabs').jqxTabs('next'); },
-   columns: [
-    { text: 'Gist', datafield: 'y_name' },
-    { text: 'Laboratorium', width: 150, datafield: 'y_laboratory' },
-    { text: 'Code', width: 90, datafield: 'y_product_id' },
-    { text: 'Soort', width: 100, datafield: 'y_form',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastFormData[value].nl + '</span>';
-     }
-    },
-    { text: 'Min. &deg;C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_min_temperature' },
-    { text: 'Max. &deg;C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_max_temperature' },
-    { text: 'Tol. %', width: 60, align: 'right', cellsalign: 'right', datafield: 'y_tolerance',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var amount = '', color = (dataRecord.est_abv > value) ? '#ff4040':'#ffffff';
-      if (value > 0) {
-       amount = dataAdapter.formatNumber(value, 'f1');
-      }
-      return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
-     }
-    },
-    { text: 'Attn. %', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_attenuation', cellsformat: 'f1' },
-    { text: 'Voor', width: 120, datafield: 'y_use',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastUseData[value].nl + '</span>';
-     }
-    },
-    { text: 'Hoeveel', datafield: 'y_amount', width: 90, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var amount = dataAdapter.formatNumber(value * 1000, 'f0') + ' ml';
-      if (rowdata.y_form == 0) // Liquid
-       amount = dataAdapter.formatNumber(value, 'f0') + ' pk';
-      else if (rowdata.y_form == 1 || rowdata.y_form == 6) // Dry
-       amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
-      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>';
-     }
-    },
-    { text: 'Voorraad', datafield: 'y_inventory', width: 90, align: 'right',
-     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-      var color, amount;
-      if (block_yeast(dataRecord.inventory_reduced, rowdata.y_use) == false) {
-       color = '#ffffff';
-       if (value < rowdata.y_amount)
-        color = '#ff4040';
-       amount = dataAdapter.formatNumber(value * 1000, 'f0') + ' ml';
-       if (rowdata.y_form == 0)        // Liquid
-        amount = dataAdapter.formatNumber(value, 'f0') + ' pk';
-       else if (rowdata.y_form == 1 || rowdata.y_form == 6)   // Dry
-        amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
-       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
-      } else {
-       return '<span></span>';
-      }
-     }
-    }
-   ]
-  });
- };
-
- // inline mash editor
- var editMash = function(data) {
-  var mashSource = {
-   localdata: data.mashs,
-   datafields: [
-    { name: 'step_name', type: 'string' },
-    { name: 'step_type', type: 'int' },
-    { name: 'step_volume', type: 'float' },
-    { name: 'step_infuse_amount', type: 'float' },
-    { name: 'step_infuse_temp', type: 'float' },
-    { name: 'step_temp', type: 'float' },
-    { name: 'step_time', type: 'float' },
-    { name: 'step_wg_ratio', type: 'float' },
-    { name: 'ramp_time', type: 'float' },
-    { name: 'end_temp', type: 'float' },
-    { name: 'step_ph', type: 'float' },
-    { name: 'step_sg', type: 'float' }
-   ],
-  },
-  mashAdapter = new $.jqx.dataAdapter(mashSource);
-
-  $('#mashGrid').jqxGrid({
-   width: 1240,
-   height: 400,
-   source: mashAdapter,
-   theme: theme,
-   selectionmode: 'singlerow',
-   editable: false,
-   ready: function() {
-    /* Calculate the whole recipe */
-    console.log('ready mashs, start calculations');
-    /* calcFermentables() must be first and is done by the grid load. Here it is too late. */
-    calcMash();
-    calcWater();
-    calcIBUs();
-    whirlpoolHops();
-    calcMiscs();
-    calcViability();
-    calcYeast();
-    kookTijd();
-    calcFermentation();
-    calcCarbonation();
-    $('#FLog').jqxButton({ disabled: (dataRecord.log_fermentation) ? false : true});
-    $('#ILog').jqxButton({ disabled: (dataRecord.log_ispindel) ? false : true});
-    $('#CLog').jqxButton({ disabled: (dataRecord.log_co2pressure) ? false : true});
-    console.log('calculations ready');
-    $('#jqxLoader').jqxLoader('close');
-    $('#jqxTabs').jqxTabs('first');
-   },
-   columns: [
-    { text: 'Stap naam', datafield: 'step_name' },
-    { text: 'Stap type', datafield: 'step_type', width: 150,
-      cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
-       return '<span style="margin: 4px; margin-top: 6px; float: left;">' + MashStepTypeData[value].nl + '</span>';
-      }
-    },
-    { text: 'Start &deg;C', datafield: 'step_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' },
-    { text: 'Eind &deg;C', datafield: 'end_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' },
-    { text: 'Rust min.', datafield: 'step_time', width: 80, align: 'right', cellsalign: 'right' },
-    { text: 'Stap min.', datafield: 'ramp_time', width: 80, align: 'right', cellsalign: 'right' },
-    { text: 'Inf/dec L.', datafield: 'step_infuse_amount', width: 80, align: 'right',
-      cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
-       if (rowdata.step_type == 1)
-        return '<span></span>';
-       var color = '#ffffff';
-       var mvol = mashkg * MaltVolume;
-       if ((rowdata.step_wg_ratio * mashkg + mvol) > dataRecord.eq_tun_volume)
-        color = '#ff4040';
-       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + dataAdapter.formatNumber(value, 'f1') + '</span>';
-      }
-    },
-    { text: 'Inf/dec &deg;C', datafield: 'step_infuse_temp', width: 90, align: 'right',
-      cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
-       if (rowdata.step_type == 1)
-        return '<span></span>';
-       return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value, 'f2') + '</span>';
-      }
-    },
-    { text: 'L/Kg.', datafield: 'step_wg_ratio', width: 80, align: 'right',
-      cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
-       var color = '#ffffff';
-       if (value < 2.0 || value > 6.0)
-        color = '#ff4040';
-       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + dataAdapter.formatNumber(value, 'f2') + '</span>';
-      }
-    },
-    { text: 'pH', datafield: 'step_ph', width: 70, align: 'right', cellsalign: 'right', cellsformat: 'f2' },
-    { text: 'SG', datafield: 'step_sg', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f3' }
-   ]
-  });
- };
-
- /*
-  * Remove the top menu so that we MUST use the button to leave the editor.
-  */
- $('#jqxMenu').jqxMenu('destroy');
- console.log('record:' + my_record + '  return:' + my_return + '  theme:' + theme);
- $('#jqxLoader').jqxLoader({ width: 250, height: 150, isModal: true, text: 'Laden product ...', theme: theme });
- $('#jqxLoader').jqxLoader('open');
-
- /* Moved to before all functions */
- dataAdapter.dataBind();
-
- /*
-  * Generic functions
-  */
- function kookTijd() {
-  if (dataRecord.boil_time) {
-   $('#brew_pmpt_koken').html('Koken ' + dataRecord.boil_time + ' minuten');
-  } else {
-   $('#brew_pmpt_koken').html('Koken "no-boil"');
-  }
- }
-
- function infusionVol(step_infused, step_mashkg, infuse_temp, step_temp, last_temp) {
-  var a = last_temp * (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + step_infused * SpecificHeatWater + step_mashkg * SpecificHeatMalt);
-  var b = step_temp * (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + step_infused * SpecificHeatWater + step_mashkg * SpecificHeatMalt);
-  var vol = Round(((b - a) / ((infuse_temp - step_temp) * SpecificHeatWater)), 2);
-  return vol;
- }
-
- function decoctionVol(step_volume, step_temp, prev_temp) {
-  var a = (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + step_volume * SpecificHeatWater) * (step_temp - prev_temp);
-  var b = SpecificHeatWater * (99 - step_temp);
-  var vol = 0;
-  if (b > 0)
-   vol = Round(a / b, 6);
-  return vol;
- }
-
- function calcViability() {
-  var vpm = 1.00;
-  var max = 100;
-  var rowscount = dataRecord.yeasts.length;
-  if (rowscount) {
-   for (i = 0; i < rowscount; i++) {
-    row = dataRecord.yeasts[i];
-    if (row.y_use == 0) {
-     if (row.y_form == 0) { // Liquid
-      vpm = 0.80;
-      max = 97;
-      if (row.y_laboratory == 'White Labs') { // PurePitch
-       vpm = 0.95;
-       max = 100;
-      }
-     } else if (row.y_form == 1) { // dry yeast
-      vpm = 0.998;
-      max = 100;
-     } else if (row.y_form == 6) { // Dried kveik
-      vpm = 0.92;
-      max = 100;
-     } else { // Slant, Culture, Frozen, Bottle
-      vpm = 0.99;
-      max = 97;
-     }
-    }
-   }
-  }
-  var base = max;
-  var days = 0;
-
-  if (parseFloat($('#yeast_prod_date').val()) > 2000) {
-   console.log('calculate viability');
-   var d = new Date();
-   var date2 = $('#yeast_prod_date').val();
-   date2 = date2.split('-');
-   // Now we convert the array to a Date object
-   var date1 = new Date(d.getFullYear(), d.getMonth(), d.getDate());
-   date2 = new Date(date2[0], date2[1] - 1, date2[2]);
-   var diff = parseInt(date1.getTime()) - parseInt(date2.getTime());
-   days = Math.floor(diff/1000/60/60/24);
-
-   var degrade = 1 - ((1 - vpm) / 30.41);  // viability degradation per day.
-   for (i = 0; i < days; i++) {
-    base = base * degrade;
-   }
-   if (base > max) {
-    base = max;
-   }
-   base = Math.round(base);
-  }
-  console.log('age:' + days + ' max:' + max + ' vpm:' + vpm + ' base:' + base);
-
-  if (dataRecord.starter_viability != base) {
-   dataRecord.starter_viability = base;
-   $('#starter_viability').val(dataRecord.starter_viability);
-  }
- }
-
- function calcSupplies() {
-  if (dataRecord.inventory_reduced > 6) {
-   $('#ok_pmpt').hide();
-   return;
-  }
-  if (ok_fermentables && ok_hops && ok_miscs && ok_yeasts && ok_waters)
-   $('#ok_supplies').html("<img src='images/dialog-ok-apply.png'>");
-  else
-   $('#ok_supplies').html("<img src='images/dialog-error.png'>");
- }
-
- /*
-  * All calculations that depend on changes in the fermentables,
-  * volumes and equipments.
-  */
- function calcFermentables() {
-
-  var sugarsf = 0,  // fermentable sugars mash + boil
-  sugarsm = 0,      // fermentable sugars in mash
-  vol = 0,          // Volume sugars after boil
-  addedS = 0,       // Added sugars after boil
-  addedmass = 0,    // Added mass after boil
-  mvol = 0,         // mash volume
-  infuse = 0,	    // mash infuse volume
-  colort = 0,       // Colors srm * vol totals
-  colorh = 0,       // Colors ebc * vol * kt
-  colorn = 0,       // Colors ebc * pt * pct
-  my_100 = false,
-  mashtime = 0,     // Total mash time
-  mashtemp = 0,     // Average mash temperature
-  bv = 0.925,       // Bierverlies rendement
-  sr = 0.95,        // Mash en spoel rendement
-  lintner = 0,      // Total recipe lintner
-  i, row, rows, org, timem, aboil_volume, spoelw, ogx, topw, s = 0, d, v, x,
-  sug, alc, pt, cw, color, scolor, fig;
-
-  /* Init global variables */
-  psugar = 0;
-  pcara = 0;
-  mashkg = 0;
-  ok_fermentables = 1;    // All is in stock.
-  ok_yeasts = 1;
-
-  if (dataRecord.mashs.length) {
-   for (i = 0; i < dataRecord.mashs.length; i++) {
-    row = dataRecord.mashs[i];
-    if (parseFloat(row.step_type) == 0) // Infusion
-     mvol += parseFloat(row.step_infuse_amount);
-    if (row.step_temp <= 75 && row.step_temp >= 60) { // Ignore mashout
-     timem = row.step_time;
-     if (i > 0)
-      timem += row.ramp_time;
-     mashtime += timem;
-     mashtemp += timem * row.step_temp;
-    }
-   }
-   infuse = mvol;
-   mashtemp = Round(mashtemp / mashtime, 2);
-  } else {
-   console.log("calcFermentables() no mash steps");
-  }
-
-  if (! dataRecord.fermentables.length) {
-   console.log("calcFermentables() no fermentables");
-   return; // grid not yet loaded.
-  }
-
-  for (i = 0; i < dataRecord.fermentables.length; i++) {
-   row = dataRecord.fermentables[i];
-   if (row.f_adjust_to_total_100)
-    my_100 = true;
-   if (row.f_type == 1 && row.f_added < 4) // Sugar
-    psugar += row.f_percentage;
-   if (row.f_graintype == 2 && row.f_added < 4)    // Crystal
-    pcara += row.f_percentage;
-   d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100);
-   if (row.f_added == 0) { // Mash
-    if (mvol > 0) { // Only if mash already known.
-     mvol += row.f_amount * row.f_moisture / 100;
-     s += d;
-    }
-    d = parseFloat(dataRecord.efficiency) / 100 * d;
-    sugarsm += d;
-    mashkg += parseFloat(row.f_amount);
-   }
-   if (row.f_added == 0 || row.f_added == 1)       // Mash or Boil
-    sugarsf += d;
-   if (row.f_added == 2 || row.f_added == 3) {     // Fermentation or lagering
-    x = (row.f_yield / 100) * (1 - row.f_moisture / 100);
-    addedS += row.f_amount * x;
-    addedmass += row.f_amount;
-    vol += (x * sugardensity + (1 - x) * 1) * row.f_amount;
-   }
-   if (row.f_added < 4) {
-    colort += row.f_amount * ebc_to_srm(row.f_color);
-    colorh += row.f_amount * row.f_color * get_kt(row.f_color);
-    colorn += (row.f_percentage / 100) * row.f_color;       // For 8.6 Pt wort.
-   }
-   if (fermentableInit) {
-    if (row.f_added == 4) {
-     $('#bottle_priming_total').val(row.f_amount * 1000);    // Prevent clearing
-     $('#bottle_priming_sugar').val(row.f_name);
-    }
-    if (row.f_added == 5) {
-     $('#keg_priming_total').val(row.f_amount * 1000);
-     $('#keg_priming_sugar').val(row.f_name);
-    }
-   }
-   // Check supplies.
-   if ((((dataRecord.inventory_reduced <= 2) && (row.f_added <= 1)) ||  // Mash or boil
-        ((dataRecord.inventory_reduced <= 3) && (row.f_added == 2)) ||  // Primary
-        ((dataRecord.inventory_reduced <= 5) && (row.f_added == 3)) ||  // Secondary or Tertiary
-        ((dataRecord.inventory_reduced <= 6) && (row.f_added == 4)) ||  // Bottle
-        ((dataRecord.inventory_reduced <= 6) && (row.f_added == 5))) && row.f_inventory < row.f_amount) {
-    ok_fermentables = 0;
-   }
-   if (row.f_added == 0 && (row.f_type == 0 || row.f_type == 4) && row.f_color < 50) { // Mash and Grain/Adjunct and Color < 50
-    lintner += row.f_diastatic_power * row.f_amount;
-   }
-  }
-  fermentableInit = 0;
-  $('#ferm_lintner').val(Math.round(parseFloat(lintner / mashkg)));
-  $('#mash_kg').val(mashkg);
-  console.log('calcFermentables() supplies:' + ok_fermentables + ' moutsuiker:' + Round(sugarsm, 3) + '/' + Round(sugarsf, 3));
-  to_100 = my_100;
-
-  if (mvol > 0) {
-   v = s / sugardensity + mvol;
-   s = 1000 * s / (v * 10); //deg. Plato
-   est_mash_sg = Round(plato_to_sg(s), 5);
-   $('#est_mash_sg').val(est_mash_sg);
-  }
-
-  // Estimate total recipe OG.
-  dataRecord.est_og = estimate_sg(sugarsf + addedS, parseFloat(dataRecord.batch_size));
-  $('#est_og').val(dataRecord.est_og);
-  $('#est_og2').val(dataRecord.est_og);
-  org = dataRecord.est_og;
-
-  // Estimate SG in kettle after boil
-  aboil_sg = estimate_sg(sugarsf, parseFloat(dataRecord.batch_size));
-  $('#est_og3').val(aboil_sg);
-
-  // Estimate SG in kettle before boil
-  preboil_sg = estimate_sg(sugarsm, parseFloat(dataRecord.boil_size));
-  $('#est_pre_sg').val(preboil_sg);
-
-  // Recalculate volumes.
-  aboil_volume = parseFloat(dataRecord.batch_size);
-  if (dataRecord.brew_aboil_volume > 0)
-   aboil_volume = dataRecord.brew_aboil_volume / 1.04;     // volume @ 20 degrees
-  if (dataRecord.brew_fermenter_tcloss == 0) {
-   dataRecord.brew_fermenter_tcloss = dataRecord.eq_trub_chiller_loss;
-   $('#brew_fermenter_tcloss').val(dataRecord.brew_fermenter_tcloss);
-  }
-  dataRecord.brew_fermenter_volume = aboil_volume - dataRecord.brew_fermenter_tcloss + dataRecord.brew_fermenter_extrawater;
-  $('#brew_fermenter_volume').val(dataRecord.brew_fermenter_volume);
-  // Calculate SG in fermenter
-  ogx = dataRecord.brew_aboil_sg;
-  if (ogx < 1.002)
-   ogx = aboil_sg;
-  topw = dataRecord.brew_fermenter_extrawater;
-
-  if (dataRecord.brew_fermenter_volume > 0) {
-   sug = sg_to_plato(ogx) * dataRecord.brew_fermenter_volume * ogx / 100;  //kg of sugar in
-   sug += addedS; //kg
-
-   if ((dataRecord.brew_fermenter_volume * ogx + addedmass) > 0) {
-    pt = 100 * sug / (dataRecord.brew_fermenter_volume * ogx + addedmass + topw);
-    dataRecord.og = dataRecord.brew_fermenter_sg = Round(plato_to_sg(pt), 4);
-    $('#brew_fermenter_sg').val(dataRecord.brew_fermenter_sg);
-    // color
-    if (dataRecord.color_method == 4) {
-     dataRecord.brew_fermenter_color = Math.round(((pt / 8.6) * colorn) + (dataRecord.boil_time / 60));
-    } else if (dataRecord.color_method == 3) {
-     dataRecord.brew_fermenter_color = Math.round((4.46 * bv * sr) / (aboil_volume + topw) * colorh);
-    } else {
-     cw = colort / (aboil_volume + topw) * 8.34436;
-     dataRecord.brew_fermenter_color = kw_to_ebc(dataRecord.color_method, cw);
-    }
-    $('#brew_fermenter_color').val(dataRecord.brew_fermenter_color);
-    scolor = ebc_to_color(dataRecord.brew_fermenter_color);
-    $('#bcolorf').show();
-    document.getElementById('bcolorf').style.background = scolor;
-   }
-  } else {
-   // Negative volume
-   dataRecord.brew_fermenter_sg = dataRecord.brew_fermenter_color = 0;
-   $('#brew_fermenter_sg').val(0);
-   $('#brew_fermenter_color').val(0);
-   $('#bcolorf').hide();
-  }
-
-  // Color of the wort
-  if (dataRecord.color_method == 4) {
-   color = Math.round(((sg_to_plato(dataRecord.est_og) / 8.6) * colorn) + (dataRecord.boil_time / 60));
-  } else if (dataRecord.color_method == 3) {      // Hans Halberstadt
-   color = Math.round((4.46 * bv * sr) / parseFloat(dataRecord.batch_size) * colorh);
-  } else {
-   cw = colort / parseFloat(dataRecord.batch_size) * 8.34436;
-   color = kw_to_ebc(dataRecord.color_method, cw);
-  }
-  dataRecord.est_color = color;
-  $('#est_color').val(color);
-  $('#est_color2').val(color);
-  scolor = ebc_to_color(color);
-  document.getElementById('bcolor').style.background = scolor;
-  document.getElementById('bcolor2').style.background = scolor;
-
-  // Progress bars
-  pmalts = mashkg / dataRecord.eq_mash_max * 100;
-  $('#perc_malts').jqxProgressBar('val', pmalts);
-  $('#perc_sugars').jqxProgressBar('val', psugar);
-  $('#perc_cara').jqxProgressBar('val', pcara);
-  calcStage();
-
-  // Calculate estimated svg.
-  svg = 0; // default.
-  initcells = 0;
-  for (i = 0; i < dataRecord.yeasts.length; i++) {
-   row = dataRecord.yeasts[i];
-   if (row.y_use == 0) {   // Primary
-    if (parseFloat(row.y_attenuation) > svg)
-     svg = parseFloat(row.y_attenuation);    // Take the highest if multiple yeasts.
-    if (row.y_form == 0)
-     initcells += (parseFloat(row.y_cells) / 1000000000) * parseFloat(row.y_amount) * (dataRecord.starter_viability / 100);
-    else
-     initcells += (parseFloat(row.y_cells) / 1000000) * parseFloat(row.y_amount) * (dataRecord.starter_viability / 100);
-   }
-   // TODO: brett in secondary ??
-   if ((((dataRecord.inventory_reduced <= 3) && (row.y_use == 0)) ||  // Primary
-        ((dataRecord.inventory_reduced <= 4) && (row.y_use == 1)) ||  // Secondary
-        ((dataRecord.inventory_reduced <= 5) && (row.y_use == 2)) ||  // Tertiary
-        ((dataRecord.inventory_reduced <= 6) && (row.y_use == 3))) && // Bottle
-        (row.y_inventory < row.y_amount)) {
-    ok_yeasts = 0;
-   }
-  }
-  calcSupplies();
-  if (svg == 0)
-   svg = 77;
-  if ((mashkg > 0) && (infuse > 0) && (mashtime > 0) && (mashtemp > 0)) {
-   dataRecord.est_fg = estimate_fg(psugar, pcara, infuse / mashkg, mashtime, mashtemp, svg, dataRecord.est_og);
-  } else {
-   dataRecord.est_fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, dataRecord.est_og);
-  }
-  $('#est_fg').val(dataRecord.est_fg);
-  $('#est_fg2').val(dataRecord.est_fg);
-  $('#est_fg3').val(dataRecord.est_fg);
-  fig = dataRecord.est_fg;
-
-  dataRecord.est_abv = abvol(dataRecord.est_og, dataRecord.est_fg);
-  $('#est_abv').val(dataRecord.est_abv);
-  $('#est_abv2').val(dataRecord.est_abv);
-
-  // Calculate the final svg if available use the real value.
-  if ((dataRecord.stage >= 6) && (dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) {
-   svg = calc_svg(dataRecord.brew_fermenter_sg, dataRecord.fg);
-   org = dataRecord.brew_fermenter_sg;
-   fig = dataRecord.fg;
-  }
-
-  $('#yeast_cells').val(initcells);
-  $('#need_cells').val(getNeededYeastCells());
-
-  // Calculate the calories in kcal/l (from brouwhulp)
-  alc = 1881.22 * fig * (org - fig) / (1.775 - org);
-  sug = 3550 * fig * (0.1808 * org + 0.8192 * fig - 1.0004);
-  $('#kcal').val(Math.round((alc + sug) / (12 * 0.0295735296)));
- };
-
- function calcMash() {
-
-  var h, m, infused = 0, mashtime = 0, mashvol = 0, vol, i, j, n, a, b, row, temp;
-  var lasttemp = 18.0;
-  var graintemp = 18.0;
-  var tuntemp = 18.0;
-
-  if (dataRecord.mashs.length && (mashkg > 0)) {
-   console.log('calcMash()');
-   for (i = 0; i < dataRecord.mashs.length; i++) {
-    row = dataRecord.mashs[i];
-    if (row.step_type == 0) { // Infusion
-     if (i == 0) {
-      // First mash step, temperature from the mashtun and malt.
-      n = 20; // tun is preheated.
-      tuntemp = row.step_temp;
-      for (j = 0; j < n; j++) {
-       a = mashkg * graintemp * SpecificHeatMalt + dataRecord.eq_tun_weight * tuntemp * dataRecord.eq_tun_specific_heat;
-       b = row.step_temp * (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + row.step_infuse_amount * SpecificHeatWater + mashkg * SpecificHeatMalt) - SlakingHeat * mashkg;
-       if (row.step_infuse_amount > 0) {
-        temp = (b - a) / (row.step_infuse_amount * SpecificHeatWater);
-       } else {
-        temp = 99;
-       }
-       tuntemp += (temp - tuntemp) / 2;
-       row.step_infuse_temp = Round(temp, 6);
-      }
-      //console.log('init infuse temp: ' + row.step_infuse_temp);
-     } else {
-      // Calculate amount of infusion water.
-      row.step_infuse_amount = infusionVol(infused, mashkg, row.step_infuse_temp, row.step_temp, lasttemp);
-      //console.log('vol: ' + row.step_infuse_amount + ' temp: ' + row.step_infuse_temp);
-     }
-     infused += parseFloat(row.step_infuse_amount);
-    } else if (row.step_type == 1) { // Temperature
-     if (i > 0)
-      row.step_infuse_amount = 0;
-     row.step_infuse_temp = 0;
-    } else if (row.step_type == 2) { // Decoction
-     row.step_infuse_amount = decoctionVol(infused, row.step_temp, lasttemp);
-     row.step_infuse_temp = 99;
-    }
-    row.step_volume = infused;
-    //console.log(i + ' type: ' + row.step_type + ' volume: ' + row.step_infuse_amount + ' temp: ' + row.step_infuse_temp);
-    lasttemp = row.step_temp;
-    mashtime += row.step_time + row.ramp_time;
-    row.step_wg_ratio = Round(infused / mashkg, 6);
-    $('#mashGrid').jqxGrid('updaterow', i, row);
-   }
-  }
-  if ((dataRecord.w1_amount + dataRecord.w2_amount) == 0) {
-    dataRecord.w1_amount = infused;
-    $('#w1_amount').val(infused);
-    console.log("calcMash() fixed water 1 to " + infused);
-  }
-  mashvol = Round(mashkg * MaltVolume + infused, 6);
-  $('#est_mashvol').val(mashvol);
-  h = Math.floor(mashtime / 60);
-  m = Math.floor(mashtime - (h * 60));
-  if (h < 10)
-    h = '0' + h;
-  if (m < 10)
-    m = '0' + m;
-  $('#est_mashtime').val(h + ':' + m);
-  // Estimated needed sparge water corrected for the temperature.
-  spoelw = Round((dataRecord.boil_size - infused + (mashkg * my_grain_absorbtion) + dataRecord.eq_lauter_deadspace) * 1.03, 6);
-  $('#brew_sparge_est').val(spoelw);
- }
-
- function getNeededYeastCells() {
-
-  var plato, volume, sg = dataRecord.brew_fermenter_sg;
-  if (sg <= 1.0001 && dataRecord.fg > 1.000)
-   sg = dataRecord.fg;
-  else if (sg <= 1.0001)
-   sg = dataRecord.est_og;
-  plato = sg_to_plato(sg);
-
-  volume = dataRecord.brew_fermenter_volume;
-  if (volume <= 0)
-   volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss;
-
-  return dataRecord.yeast_pitchrate * volume * plato;
- }
-
- function hopFlavourContribution(bt, vol, use, amount) {
-  var result;
-
-  if (use == 4 || use == 5) // Whirlpool or Dry-hop
-   return 0;
-  if (use == 1) { // First wort
-   result = 0.15;          // assume 15% flavourcontribution for fwh
-  } else if (bt > 50) {
-   result = 0.10;          // assume 10% flavourcontribution as a minimum
-  } else {
-   result = 15.25 / (6 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 21) / 6, 2));
-   if (result < 0.10)
-    result = 0.10;  // assume 10% flavourcontribution as a minimum
-  }
-  return (result * amount * 1000) / vol;
- }
-
- function hopAromaContribution(bt, vol, use, amount) {
-  var result = 0;
-
-  if (use == 5) { // Dry hop
-   result = 1.33;
-  } else if (use == 4) { // Whirlpool
-   if (bt > 30)
-    bt = 30; // Max 30 minutes
-   result = 0.62 * bt / 30;
-  } else if (bt > 20) {
-   result = 0;
-  } else if (bt > 7.5) {
-   result = 10.03 / (4 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 7.5) / 4, 2));
-  } else if (use == 2) {  // Boil
-   result = 1;
-  } else if (use == 3) {  // Aroma
-   result = 1.2;
-  }
-  return (result * amount * 1000) / vol;
- }
-
- function calcIBUs() {
-  var total_ibus = 0, ferm_ibus = 0, rows = {}, i, row;
-  hop_aroma = hop_flavour = 0;
-  if (!(rows = $('#hopGrid').jqxGrid('getrows'))) {
-   return;
-  }
-  ok_hops = 1;
-  for (i = 0; i < rows.length; i++) {
-   row = rows[i];
-   total_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.batch_size),
-    parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method,
-    dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6);
-   ferm_ibus += toIBU(row.h_useat, row.h_form, preboil_sg,
-    parseFloat(dataRecord.brew_fermenter_volume) + parseFloat(dataRecord.brew_fermenter_tcloss),
-    parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method,
-    dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6);
-   hop_flavour += hopFlavourContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount));
-   hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount));
-   if ((((dataRecord.inventory_reduced <= 2) && (row.h_useat <= 4)) ||  // Mash, FW, Boil, Aroma, Whirlpool
-        ((dataRecord.inventory_reduced <= 6) && (row.h_useat == 5))) && // Dry-hop
-        (row.h_inventory < row.h_amount))
-    ok_hops = 0;
-  }
-  total_ibus = Round(total_ibus, 1);
-  ferm_ibus = Round(ferm_ibus, 1);
-  hop_flavour = Round(hop_flavour * 100 / 5, 1);
-  hop_aroma = Round(hop_aroma * 100 / 6, 1);
-  if (hop_flavour > 100)
-   hop_flavour = 100;
-  if (hop_aroma > 100)
-   hop_aroma = 100;
-  console.log('calcIBUs(): ' + total_ibus + ' flavour: ' + hop_flavour + ' aroma: ' + hop_aroma +
-               ' fermenter:' + ferm_ibus + ' supplies:' + ok_hops);
-  dataRecord.est_ibu = total_ibus;
-  $('#est_ibu').val(total_ibus);
-  $('#est_ibu2').val(total_ibus);
-  $('#hop_flavour').jqxProgressBar('val', hop_flavour);
-  $('#hop_aroma').jqxProgressBar('val', hop_aroma);
-  $('#brew_fermenter_ibu').val(ferm_ibus);
-  calcStage();
-  calcSupplies();
- };
-
- /*
-  * http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
-  *
-  * stype: 0=stirred, 1=shaken, 2=simple
-  * totcells: initial cells
-  * egrams: gram extract
-  */
- function getGrowthRate(stype, totcells, egrams) {
-
-  /* Cells per grams extract (B/g) */
-  var cpe = totcells / egrams;
-
-  if (cpe > 3.5)
-   return 0;       // no growth
-  if (stype == 2)
-   return 0.4;     // simple starter
-  if (stype == 1)
-   return 0.62;    // shaken starter
-  if (cpe <= 1.4)  // stirred starter
-   return 1.4;
-  return 2.33 - (.67 * cpe);
- };
-
- function calcStep(svol, stype, start) {
-
-  var gperpoint = 2.72715,  //number of grams of extract per point of starter gravity per liter
-  prate = start / svol * 1000,
-  irate = Round(prate, 1),
-  egrams = (dataRecord.starter_sg - 1) * svol * gperpoint,
-  grate = getGrowthRate(stype, start, egrams),
-  ncells = Round(egrams * grate, 1),
-  totcells = parseFloat(ncells) + start;
-
-  return {
-   svol: svol,
-   irate: irate,
-   prate: Round(prate, 1),
-   ncells: ncells,
-   totcells: totcells,
-   growf: Round(ncells / start, 2)
-  };
- }
-
- function killstep2() {
-
-  dataRecord.prop2_volume = 0;
-  $('#prop2_volume').val(0);
-  $('#prop2_tcells').val(0);
-  $('#prop2_type,#prop2_volume,#prop2_irate,#prop2_ncells,#prop2_tcells,#prop2_growf').hide();
-  $('#r2_pmpt').show();
- }
-
- function killstep3() {
-
-  dataRecord.prop3_volume = 0;
-  $('#prop3_volume').val(0);
-  $('#prop3_tcells').val(0);
-  $('#prop3_type,#prop3_volume,#prop3_irate,#prop3_ncells,#prop3_tcells,#prop3_growf').hide();
-  $('#r3_pmpt').show();
- }
-
- function killstep4() {
-
-  dataRecord.prop4_volume = 0;
-  $('#prop4_volume').val(0);
-  $('#prop4_tcells').val(0);
-  $('#prop4_type,#prop4_volume,#prop4_irate,#prop4_ncells,#prop4_tcells,#prop4_growf').hide();
-  $('#r4_pmpt').show();
- }
-
- /*
-  * Calculate all starter steps.
-  * stype: final starter type: 0 = stirred, 1 = shaked, 2 = simple.
-  * start: initial cells in billions
-  * needed: needed cells in billions
-  *
-  * result: all values updated.
-  */
- function calcSteps(stype, start, needed) {
-
-  var uvols = [20, 40, 60, 80, 100, 150, 200, 250, 375, 500, 625, 750, 875, 1000, 1250, 1500, 2000, 2500, 3000, 4000, 5000],
-      mvols = uvols.length, svol = 0, lasti = 0, result = {}, i;
-
-  /*
-   * If no values are set, auto calculate the starter.
-   */
-  if ((parseFloat($('#prop1_volume').jqxNumberInput('decimal')) + parseFloat($('#prop2_volume').jqxNumberInput('decimal')) +
-       parseFloat($('#prop3_volume').jqxNumberInput('decimal')) + parseFloat($('#prop4_volume').jqxNumberInput('decimal'))) == 0) {
-   // clear by default
-   for (i = 1; i < 5; i++) {
-    $('#prop' + i + '_type,#prop' + i + '_volume,#prop' + i + '_irate,#prop' + i + '_ncells,#prop' + i + '_tcells,#prop' + i + '_growf').hide();
-    $('#r' + i + '_pmpt').show();
-    $('#prop' + i + '_type').val(stype);
-    $('#prop' + i + '_volume').val(0);
-   }
-   if (start > needed) {
-    return; // no starter needed
-   }
-   $('#prop1_type,#prop1_volume,#prop1_irate,#prop1_ncells,#prop1_tcells,#prop1_growf').show();
-   $('#r1_pmpt').hide();
-   for (i = lasti; i <= mvols; i++) {
-    lasti = i;
-    svol = uvols[lasti];
-    result = calcStep(svol, stype, start);
-    if (result.irate < 25) {
-     // inocculation rate too low, backup one step and break out.
-     lasti = i - 1;
-     svol = uvols[lasti];
-     result = calcStep(svol, stype, start);
-     break;
-    }
-    if (result.totcells > needed || i == mvols) { // hit the target or loops done
-     break;
-    }
-   }
-   $('#prop1_volume').val(result.svol / 1000); // to liters
-   $('#prop1_irate').val(result.prate);
-   $('#prop1_ncells').val(result.ncells);
-   $('#prop1_tcells').val(result.totcells);
-   $('#prop1_growf').val(result.growf);
-   if (result.totcells > needed)
-    return; // hit the target
-
-   // second stage
-   $('#r2_pmpt').hide();
-   $('#prop2_type').val(stype);
-   $('#prop2_type,#prop2_volume,#prop2_irate,#prop2_ncells,#prop2_tcells,#prop2_growf').show();
-   for (i = lasti; i <= mvols; i++) {
-    lasti = i;
-    svol = uvols[lasti];
-    result = calcStep(svol, stype, $('#prop1_tcells').val());
-    if (result.irate < 25) {
-     lasti = i - 1;
-     svol = uvols[lasti];
-     result = calcStep(svol, stype, $('#prop1_tcells').val());
-     break;
-    }
-    if (result.totcells > needed || i == mvols) { // hit the target or loops done
-     break;
-    }
-   }
-   $('#prop2_volume').val(result.svol / 1000); // to liters
-   $('#prop2_irate').val(result.prate);
-   $('#prop2_ncells').val(result.ncells);
-   $('#prop2_tcells').val(result.totcells);
-   $('#prop2_growf').val(result.growf);
-   if (result.totcells > needed)
-    return; // hit the target
-
-   // third stage
-   $('#r3_pmpt').hide();
-   $('#prop3_type').val(stype);
-   $('#prop3_type,#prop3_volume,#prop3_irate,#prop3_ncells,#prop3_tcells,#prop3_growf').show();
-   for (i = lasti; i <= mvols; i++) {
-    lasti = i;
-    svol = uvols[lasti];
-    result = calcStep(svol, stype, $('#prop2_tcells').val());
-    if (result.irate < 25) {
-     lasti = i - 1;
-     svol = uvols[lasti];
-     result = calcStep(svol, stype, $('#prop2_tcells').val());
-     break;
-    }
-    if (result.totcells > needed || i == mvols) { // hit the target or loops done
-     break;
-    }
-   }
-   $('#prop3_volume').val(result.svol / 1000); // to liters
-   $('#prop3_irate').val(result.prate);
-   $('#prop3_ncells').val(result.ncells);
-   $('#prop3_tcells').val(result.totcells);
-   $('#prop3_growf').val(result.growf);
-   if (result.totcells > needed)
-    return; // hit the target
-
-   // fourth stage
-   $('#r4_pmpt').hide();
-   $('#prop4_type').val(stype);
-   $('#prop4_type,#prop4_volume,#prop4_irate,#prop4_ncells,#prop4_tcells,#prop4_growf').show();
-   for (i = lasti; i <= mvols; i++) {
-    lasti = i;
-    svol = uvols[lasti];
-    result = calcStep(svol, stype, $('#prop3_tcells').val());
-    if (result.totcells > needed || i == mvols) { // hit the target or loops done
-     $('#prop4_volume').val(result.svol / 1000); // to liters
-     $('#prop4_irate').val(result.prate);
-     $('#prop4_ncells').val(result.ncells);
-     $('#prop4_tcells').val(result.totcells);
-     $('#prop4_growf').val(result.growf);
-     return;
-    }
-   }
-  } else {
-   // recalculate
-   if (dataRecord.prop1_volume > 0) {
-    $('#r1_pmpt').hide();
-    $('#prop1_type,#prop1_volume,#prop1_irate,#prop1_ncells,#prop1_tcells,#prop1_growf').show();
-    result = calcStep($('#prop1_volume').val() * 1000, dataRecord.prop1_type, start);
-    $('#prop1_irate').val(result.prate);
-    $('#prop1_ncells').val(result.ncells);
-    $('#prop1_tcells').val(result.totcells);
-    $('#prop1_growf').val(result.growf);
-    if (result.totcells > needed) {
-     killstep2();
-     killstep3();
-     killstep4();
-    } else if (dataRecord.prop2_volume == 0) {
-     dataRecord.prop2_volume = dataRecord.prop1_volume; /* Extra step needed, start with the same size */
-     dataRecord.prop2_type = dataRecord.prop1_type;
-     $('#prop2_volume').val(dataRecord.prop2_volume);
-     $('#prop2_type').val(dataRecord.prop2_type);
-    }
-   }
-   if (dataRecord.prop2_volume > 0) {
-    $('#r2_pmpt').hide();
-    $('#prop2_type,#prop2_volume,#prop2_irate,#prop2_ncells,#prop2_tcells,#prop2_growf').show();
-    result = calcStep($('#prop2_volume').val() * 1000, dataRecord.prop2_type, $('#prop1_tcells').val());
-    $('#prop2_irate').val(result.prate);
-    $('#prop2_ncells').val(result.ncells);
-    $('#prop2_tcells').val(result.totcells);
-    $('#prop2_growf').val(result.growf);
-    if (result.totcells > needed) {
-     killstep3();
-     killstep4();
-    } else if (dataRecord.prop3_volume == 0) {
-     dataRecord.prop3_volume = dataRecord.prop2_volume; /* Extra step needed, start with the same size */
-     dataRecord.prop3_type = dataRecord.prop2_type;
-     $('#prop3_volume').val(dataRecord.prop3_volume);
-     $('#prop3_type').val(dataRecord.prop3_type);
-    }
-   }
-   if (dataRecord.prop3_volume > 0) {
-    $('#r3_pmpt').hide();
-    $('#prop3_type,#prop3_volume,#prop3_irate,#prop3_ncells,#prop3_tcells,#prop3_growf').show();
-    result = calcStep($('#prop3_volume').val() * 1000, dataRecord.prop3_type, $('#prop2_tcells').val());
-    $('#prop3_irate').val(result.prate);
-    $('#prop3_ncells').val(result.ncells);
-    $('#prop3_tcells').val(result.totcells);
-    $('#prop3_growf').val(result.growf);
-    if (result.totcells > needed) {
-     killstep4();
-    } else if (dataRecord.prop4_volume == 0) {
-     dataRecord.prop4_volume = dataRecord.prop3_volume; /* Extra step needed, start with the same size */
-     dataRecord.prop4_type = dataRecord.prop3_type;
-     $('#prop4_volume').val(dataRecord.prop4_volume);
-     $('#prop4_type').val(dataRecord.prop4_type);
-    }
-   }
-   if (dataRecord.prop4_volume > 0) {
-    $('#r4_pmpt').hide();
-    $('#prop4_type,#prop4_volume,#prop4_irate,#prop4_ncells,#prop4_tcells,#prop4_growf').show();
-    result = calcStep($('#prop4_volume').val() * 1000, dataRecord.prop4_type, $('#prop3_tcells').val());
-    $('#prop4_irate').val(result.prate);
-    $('#prop4_ncells').val(result.ncells);
-    $('#prop4_tcells').val(result.totcells);
-    $('#prop4_growf').val(result.growf);
-   }
-  }
- }
-
- function calcYeast() {
-
-  // Calculate needed cells.
-  var plato, volume, rows, rowscount, row, i, needed, use_cells, sg = dataRecord.brew_fermenter_sg;
-
-  if (sg <= 1.0001 && dataRecord.fg > 1.000)
-   sg = dataRecord.fg;
-  else if (sg <= 1.0001)
-   sg = dataRecord.est_og;
-  plato = sg_to_plato(sg);
-
-  volume = dataRecord.brew_fermenter_volume;
-  if (volume > 0) {
-   if (dataRecord.brew_fermenter_extrawater > 0)
-    volume += dataRecord.brew_fermenter_extrawater;
-  } else {
-   volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss;
-  }
-
-  // Also in calcFermentables()
-  $('#yeast_cells').val(initcells);
-
-  if (!(rows = $('#yeastGrid').jqxGrid('getrows'))) {
-   return; // grid not yet loaded.
-  }
-  rowscount = dataRecord.yeasts.length;
-  if (rowscount == 0)
-   return; // no yeast in recipe
-
-  $('.primary_dry').hide();
-  $('.primary_liquid').hide();
-
-  var maybe_starter = 0;
-  var pitchrate = 0.75;    // Yeast pitch rate default
-  for (i = 0; i < rowscount; i++) {
-   row = dataRecord.yeasts[i];
-   if (row.y_use == 0) { // primary
-    if (row.y_form == 1) {
-     // Dry yeast
-     $('.primary_dry').show();
-     console.log('dry yeast: ' + row.y_gr_hl_lo + '@' + row.y_sg_lo + '  ' + row.y_gr_hl_hi + '@' + row.y_sg_hi);
-     // Build the formule with the yeast parameters.
-     // Based on https://www.lallemandbrewing.com/en/canada/brewers-corner/brewing-tools/pitching-rate-calculator/
-     var og = row.y_sg_lo;
-     var f1 = row.y_gr_hl_lo / 100;
-     var f2 = Round(f1 / 5, 6);
-     // After a lot of try and error, study, the best thing to increase the pitch amount is actually
-     // use this simple formula by Lallemand. This is about the same as sugar weight increment in the wort.
-     var multiplier = (sg <= og) ? f1 : (f1 + f2 * (sg - og) / 0.008);
-     console.log('sg: ' + sg + ' og: ' + og + ' f1: ' + f1 + ' f2: ' + f2 + ' multiplier: ' + multiplier);
-     // dataRecord.starter_viability
-     var yeast_grams = Round(volume * multiplier * (100 / dataRecord.starter_viability), 2);
-     $('#yeast_grams').val(yeast_grams);
-     var yeast_gr_hl = Round(yeast_grams / (volume * 0.01), 2);
-     $('#yeast_gr_hl').val(yeast_gr_hl);
-     //console.log('need ' + yeast_grams + ' grams, gr/hl: ' + yeast_gr_hl);
-
-    } else {
-     // Liquid yeast
-     $('.primary_liquid').show();
-     // pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/
-     // and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
-     if (row.y_type == 0) { // lager yeast
-      pitchrate = 1.5;
-      if (dataRecord.est_og > 1.060)
-       pitchrate = 2.0;
-     } else if (row.y_type == 6) { // Kveik
-      pitchrate = 0.075;
-     } else {
-      pitchrate = 0.75;
-      if (dataRecord.est_og > 1.060)
-       pitchrate = 1.0;
-     }
-     if (dataRecord.yeast_pitchrate < 0.01) {
-      dataRecord.yeast_pitchrate = pitchrate;
-      $('#yeast_pitchrate').val(pitchrate);
-     }
-     maybe_starter = 1;
-    }
-   }
-  }
-
-  needed = Round(dataRecord.yeast_pitchrate * volume * plato, 1);
-  $('#need_cells').val(needed);
-  use_cells = initcells;
-  if (needed <= initcells)
-   maybe_starter = 0;
-  //console.log('calcYeast() pitchrate:' + dataRecord.yeast_pitchrate + ' start:' + initcells + ' needed:' + needed + ' volume:' + volume + ' maybe_starter:' + maybe_starter);
-
-  if (maybe_starter != dataRecord.starter_enable) {
-   dataRecord.starter_enable = maybe_starter;
-  }
-  if (maybe_starter)
-   $('#propagator').show();
-  else
-   $('#propagator').hide();
-
-  if (dataRecord.starter_enable) {
-
-   calcSteps(dataRecord.starter_type, initcells, needed);
-
-   for (i = 1; i < 5; i++) {
-    $('#r' + i + '_irate').html('');
-    $('#r' + i + '_growf').html('');
-    $('#r' + i + '_tcells').html('');
-    if (parseFloat($('#prop' + i + '_volume').val()) > 0) {
-     if ((parseFloat($('#prop' + i + '_irate').val()) < 25) || (parseFloat($('#prop' + i + '_irate').val()) > 100)) {
-      $('#r' + i + '_irate').html("<img src='images/dialog-error.png'>");
-     } else {
-      $('#r' + i + '_irate').html("<img src='images/dialog-ok-apply.png'>");
-     }
-     if (parseFloat($('#prop' + i + '_growf').val()) < 1)
-      $('#r' + i + '_growf').html("<img src='images/dialog-error.png'>");
-     if (($('#prop' + i + '_type').val() > 0) && (parseFloat($('#prop' + i + '_growf').val()) > 3))
-      $('#r' + i + '_growf').html("<img src='images/dialog-error.png'>");
-     if (parseFloat($('#prop' + i + '_tcells').val()) > needed)
-      $('#r' + i + '_tcells').html("<img src='images/dialog-ok-apply.png'>");
-     use_cells = parseFloat($('#prop' + i + '_tcells').val());
-    } else {
-     $('#r' + i + '_irate').html('');
-    }
-   }
-  }
-  $('#plato_cells').val(parseFloat(use_cells / (volume * plato)));
- };
-
- function whirlpoolHops() {
-  var row, i, time, rowscount = dataRecord.hops.length;
-  if (rowscount == 0)
-   return;
-  for (i = 0; i < rowscount; i++) {
-   row = dataRecord.hops[i];
-   if (row.h_useat == 4) {
-    time = parseFloat(dataRecord.brew_whirlpool9) + parseFloat(dataRecord.brew_whirlpool7) + parseFloat(dataRecord.brew_whirlpool6);
-    dataRecord.hops[i].h_time = time;
-    $('#hopGrid').jqxGrid('setcellvalue', i, 'h_time', time);
-   }
-  }
- };
-
- function calcMiscs() {
-
-  ok_miscs = 1;
-  var row, i, rowscount = dataRecord.miscs.length;
-  if (rowscount == 0)
-   return;
-  for (i = 0; i < rowscount; i++) {
-   row = dataRecord.miscs[i];
-   if ((((dataRecord.inventory_reduced <= 2) && (row.m_use_use <= 2)) ||  // Starter, Mash, Boil
-	((dataRecord.inventory_reduced <= 2) && (row.m_use_use == 6)) ||  // Sparge
-        ((dataRecord.inventory_reduced <= 3) && (row.m_use_use == 3)) ||  // Primary
-        ((dataRecord.inventory_reduced <= 5) && (row.m_use_use == 4)) ||  // Secondary, Teriary
-        ((dataRecord.inventory_reduced <= 6) && (row.m_use_use == 5))) && // Bottle
-        (row.m_inventory < row.m_amount)) {
-    ok_miscs = 0;
-   }
-  }
-  calcSupplies();
- };
-
- function GetBUGU() {
-  var gu = (dataRecord.est_og - 1) * 1000;
-  if (gu > 0)
-   return dataRecord.est_ibu / gu;
-  else
-   return 0.5;
- }
-
- function GetOptSO4Clratio() {
-   var BUGU = GetBUGU();
-   return (1.0 / (-1.2 * BUGU + 1.4));
- }
-
- function setWaterAgent(name, amount, use) {
-  var row, i, id, found = false, miscs, rows = $('#miscGrid').jqxGrid('getrows');
-  if (amount == 0) {
-   for (i = 0; i < rows.length; i++) {
-    row = rows[i];
-    if (row.m_name == name && row.m_use_use == use) {
-     id = $('#miscGrid').jqxGrid('getrowid', i);
-     $('#miscGrid').jqxGrid('deleterow', id);
-    }
-   }
-  } else {
-   for (i = 0; i < rows.length; i++) {
-    row = rows[i];
-    if (row.m_name == name && row.m_use_use == use) {
-     found = true;
-     $('#miscGrid').jqxGrid('setcellvalue', i, 'm_amount', amount / 1000);
-     break;
-    }
-   }
-   if (! found) {
-    miscs = new $.jqx.dataAdapter(miscInvSource, {
-     loadComplete: function() {
-      var record, i, row = {}, records = miscs.records;
-      for (i = 0; i < records.length; i++) {
-       record = records[i];
-       if (record.name == name) {
-        row['m_name'] = record.name;
-        row['m_amount'] = amount / 1000;
-        row['m_cost'] = record.cost;
-        row['m_type'] = record.type;
-        row['m_use_use'] = use;
-        row['m_time'] = 0;
-        row['m_amount_is_weight'] = record.amount_is_weight;
-        row['m_inventory'] = record.inventory;
-        row['m_avail'] = 1;
-        $('#miscGrid').jqxGrid('addrow', null, row);
-       }
-      }
-     }
-    });
-    miscs.dataBind();
-    return;
-   }
-  }
- }
-
- function setRangeIndicator(ion, rangeCode) {
-  if ((rangeCode == 'laag') || (rangeCode == 'hoog'))
-   $('#wr_' + ion).html("<img src='images/dialog-error.png'><span style='vertical-align: top; font-size: 10px; font-style: italic;'>" + rangeCode + '</span>');
-  else
-   $('#wr_' + ion).html("<img src='images/dialog-ok-apply.png'>");
- }
-
- function mix(v1, v2, c1, c2) {
-  if ((v1 + v2) > 0) {
-   return ((v1 * c1) + (v2 * c2)) / (v1 + v2);
-  }
-  return 0;
- }
-
- function PartCO3(pH) {
-  var H = Math.pow(10, -pH);
-  return 100 * Ka1 * Ka2 / (H * H + H * Ka1 + Ka1 * Ka2);
- }
-
- function PartHCO3(pH) {
-  var H = Math.pow(10, -pH);
-  return 100 * Ka1 * H / (H * H + H * Ka1 + Ka1 * Ka2);
- }
-
- function Charge(pH) {
-  return (-2 * PartCO3(pH) - PartHCO3(pH));
- }
-
- //Z alkalinity is the amount of acid (in mEq/l) needed to bring water to the target pH (Z pH)
- function ZAlkalinity(pHZ) {
-  var C43 = Charge(4.3),
-  Cw = Charge(parseFloat($('#wg_ph').jqxNumberInput('decimal'))),
-  Cz = Charge(pHZ),
-  DeltaCNaught = -C43 + Cw,
-  CT = parseFloat($('#wg_total_alkalinity').jqxNumberInput('decimal')) / 50 / DeltaCNaught,
-  DeltaCZ = -Cz + Cw;
-  return CT * DeltaCZ;
- }
-
- //Z Residual alkalinity is the amount of acid (in mEq/l) needed to bring the water in the mash to the target pH (Z pH)
- function ZRA(pHZ) {
-
-  var Magn, Z, Calc = parseFloat($('#wg_calcium').jqxNumberInput('decimal')) / (MMCa / 2);
-  Magn = parseFloat($('#wg_magnesium').jqxNumberInput('decimal')) / (MMMg / 2);
-  Z = ZAlkalinity(pHZ);
-  return Z - (Calc / 3.5 + Magn / 7);
- }
-
- function BufferCapacity(di_ph, acid_to_ph_57, ebc, graintype) {
-  C1 = 0;
-  if ((di_ph != 5.7) && ((acid_to_ph_57 < - 0.1) || (acid_to_ph_57 > 0.1))) {
-      C1 = acid_to_ph_57 / (di_ph - 5.7);
-  } else {
-      // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid.
-      switch (graintype) {
-       case 0:                                 // Base, Special, Kilned
-       case 3:
-       case 5: C1 = 0.014 * ebc - 34.192;
-               break;
-       case 2: C1 = -0.0597 * ebc - 32.457;    // Crystal
-               break;
-       case 1: C1 = 0.0107 * ebc - 54.768;     // Roast
-               break;
-       case 4: C1 = -149;                      // Sour malt
-               break;
-      }
-  }
-  return C1;
- }
-
- function ProtonDeficit(pHZ) {
-
-  var i, C1, x, Result = ZRA(pHZ) * parseFloat($('#wg_amount').jqxNumberInput('decimal'));
-  // proton deficit for the grist
-  if (( $('#fermentableGrid').jqxGrid('getrows'))) {
-   for (i = 0; i < dataRecord.fermentables.length; i++) {
-    row = dataRecord.fermentables[i];
-    if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt
-     C1 = BufferCapacity(row.f_di_ph, row.f_acid_to_ph_57, row.f_color, row.f_graintype);
-     x = C1 * (pHZ - row.f_di_ph);   // AcidRequired(ZpH)
-     Result += x * row.f_amount;
-    }
-   }
-  } else {
-   error_count++;
-   if (error_count < 5)
-    console.log('ProtonDeficit(' + pHZ + ') invalid grist, return ' + Result);
-  }
-  return Result;
- }
-
- function MashpH() {
-
-  var n = 0, pH = 5.4, deltapH = 0.001, deltapd = 0.1, pd = ProtonDeficit(pH);
-  while (((pd < -deltapd) || (pd > deltapd)) && (n < 2000)) {
-   n++;
-   if (pd < -deltapd)
-    pH -= deltapH;
-   else if (pd > deltapd)
-    pH += deltapH;
-   pd = ProtonDeficit(pH);
-  }
-  pH = Round(pH, 6);
-  //console.log('MashpH() n: ' + n + ' pH: ' + pH);
-  return pH;
- }
-
- function calcWater() {
-
-  /* Can be called during loading and building the screens */
-  if (! data_loaded) {
-   console.log('calcWater() failsave');
-   return;
-  }
-
-  var liters = 0,
-  calcium = 0,
-  magnesium = 0,
-  sodium = 0,
-  total_alkalinity = 0,
-  chloride = 0,
-  sulfate = 0,
-  ph = 0,
-  RA = 0,
-  frac = 0,
-  TpH = 0,
-  protonDeficit = 0,
-  AT, /*BT,*/
-  r1d, r2d, f1d, f2d, f3d,
-  deltapH, deltapd, pd, n,
-  Res;
-
-  if (dataRecord.w1_name == '') {
-   return;
-  }
-
-  $('#w1_hardness').val(Hardness(dataRecord.w1_calcium, dataRecord.w1_magnesium));
-  $('#w1_ra').val(ResidualAlkalinity(dataRecord.w1_total_alkalinity, dataRecord.w1_calcium, dataRecord.w1_magnesium));
-
-  // If there is a dillute water source, mix the waters.
-  if ((dataRecord.w2_name != '') && (dataRecord.w2_name != 'Geen mengwater')) {
-   liters = dataRecord.w1_amount + dataRecord.w2_amount;
-   calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium);
-   magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium);
-   sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium);
-   chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride);
-   sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate);
-   total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity);
-   ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters);
-   $('#w2_hardness').val(Hardness(dataRecord.w2_calcium, dataRecord.w2_magnesium));
-   $('#w2_ra').val(ResidualAlkalinity(dataRecord.w2_total_alkalinity, dataRecord.w2_calcium, dataRecord.w2_magnesium));
-  } else {
-   liters = dataRecord.w1_amount;
-   calcium = dataRecord.w1_calcium;
-   magnesium = dataRecord.w1_magnesium;
-   sodium = dataRecord.w1_sodium;
-   chloride = dataRecord.w1_chloride;
-   sulfate = dataRecord.w1_sulfate;
-   total_alkalinity = dataRecord.w1_total_alkalinity;
-   ph = dataRecord.w1_ph;
-  }
-  var bicarbonate = Bicarbonate(total_alkalinity, ph);
-
-  /* Save mixed water ions for later */
-  var wg_calcium = calcium;
-  var wg_sodium = sodium;
-  var wg_total_alkalinity = total_alkalinity;
-  var wg_chloride = chloride;
-  var wg_sulfate = sulfate;
-  var wg_bicarbonate = bicarbonate;
-
-  dataRecord.wg_amount = liters;
-  dataRecord.wg_ph = ph;
-
-  $('#wg_amount').val(liters);
-  $('#wg_calcium').val(Round(calcium, 1));
-  $('#wg_magnesium').val(Round(magnesium, 1));
-  $('#wg_sodium').val(Round(sodium, 1));
-  $('#wg_bicarbonate').val(Round(bicarbonate, 1));
-  $('#wg_total_alkalinity').val(Round(total_alkalinity, 1));
-  $('#wg_chloride').val(Round(chloride, 1));
-  $('#wg_sulfate').val(Round(sulfate, 1));
-  $('#wg_ph').val(Round(ph, 2));
-  $('#wg_hardness').val(Round(Hardness(calcium, magnesium), 1));
-  $('#wg_ra').val(Round(ResidualAlkalinity(total_alkalinity, calcium, magnesium), 1));
-
-  var mash_ph = Round(MashpH(), 3);
-  console.log('Distilled water mash pH: ' + mash_ph);
-
-  /* Calculate Salt additions */
-  if (liters > 0) {
-   calcium += (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 +
-    parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000 +
-    parseFloat($('#wa_caco3').jqxNumberInput('decimal')) * MMCa / MMCaCO3 * 1000) / liters;
-   magnesium += (parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4 * 1000 +
-    parseFloat($('#wa_mgcl2').jqxNumberInput('decimal')) * MMMg / MMMgCl2 * 1000) / liters;
-   sodium += (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 +
-    parseFloat($('#wa_nahco3').jqxNumberInput('decimal')) * MMNa / MMNaHCO3 * 1000) / liters;
-   sulfate += (parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 * 1000 +
-    parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 * 1000) / liters;
-   chloride += (2 * parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 * 1000 +
-    parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl * 1000 +
-    parseFloat($('#wa_mgcl2').jqxNumberInput('decimal')) * MMCl / MMMgCl2 * 1000) / liters;
-   bicarbonate += (parseFloat($('#wa_nahco3').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3 * 1000 +
-    parseFloat($('#wa_caco3').jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3 * 1000) / liters;
-  }
-
-  if (dataRecord.wa_acid_name < 0 || dataRecord,wa_acid_name >= AcidTypeData.length) {
-   $('#wa_acid_name').val(0);
-   dataRecord.wa_acid_name = 0;
-   dataRecord.wa_acid_perc = AcidTypeData[0].AcidPrc;
-   $('#wa_acid_perc').val(AcidTypeData[0].AcidPrc);
-  }
-  if (last_acid == '')
-   last_acid = AcidTypeData[dataRecord.wa_acid_name].nl;
-
-  if (parseFloat(dataRecord.wa_acid_perc) == 0) {
-   dataRecord.wa_acid_perc = AcidTypeData[AT].AcidPrc;
-   $('#wa_acid_perc').val(AcidTypeData[AT].AcidPrc);
-  }
-
-  AT = dataRecord.wa_acid_name;
-
-  /* Note that the next calculations do not correct the pH change by the added salts.
-     This pH change is at most 0.1 pH and is a minor difference in Acid amount. */
-
-  if (dataRecord.calc_acid) {
-   /* Auto calculate pH */
-   $('.c_mashph').show();
-   TpH = parseFloat(dataRecord.mash_ph);
-   protonDeficit = ProtonDeficit(TpH);
-   //console.log('calc_acid tgt: ' + TpH + ' protonDeficit: ' + protonDeficit);
-   if (protonDeficit > 0) { // Add acid
-    frac = CalcFrac(TpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
-    Acid = protonDeficit / frac;
-    Acid *= AcidTypeData[AT].MolWt; // mg
-    Acidmg = Acid;
-    var RealSG = Round(((AcidTypeData[AT].AcidSG - 1000) * (parseFloat(dataRecord.wa_acid_perc) / 100)) + 1000, 2);
-    Acid /= RealSG;
-    Acid /= AcidTypeData[AT].AcidPrc / 100;
-    Acid = Round(Acid, 2);
-    console.log('Mash auto Acid final ml: ' + Acid);
-    $('#wa_acid').val(Acid);
-    setWaterAgent(AcidTypeData[AT].nl, Acid, 1);
-
-    bicarbonate = bicarbonate - protonDeficit * frac / liters;
-    total_alkalinity = bicarbonate * 50 / 61;
-   }
-   ph = TpH;
-   dataRecord.wb_ph = ph;
-   $('#wb_ph').val(Round(ph, 2));
-   $('#est_mash_ph').val(Round(ph, 2));
-  } else {
-   /* Manual calculate pH */
-   $('.c_mashph').hide();
-   console.log('calc_acid no');
-   pHa = Round(ph, 3); // Adjusted water pH
-   // Then calculate the new pH with added acids and malts
-   console.log('Mash pH: ' + pHa);
-   Acid  = AcidTypeData[AT].AcidSG * (parseFloat(dataRecord.wa_acid_perc) / 100); // ml
-   Acid *= parseFloat($('#wa_acid').jqxNumberInput('decimal'));
-   Acid /= AcidTypeData[AT].MolWt;  // mg
-   Acidmg = Acid;
-
-   //find the pH where the protondeficit = protondeficit by the acid
-   frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
-   protonDeficit = Round(Acid * frac, 3);
-   //console.log('protonDeficit Acid: ' + protonDeficit + ' frac: ' + frac + ' pH: ' + pHa);
-
-   deltapH = 0.001;
-   deltapd = 0.1;
-   pd = Round(ProtonDeficit(pHa), 6);
-   n = 0;
-   while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 4000)) {
-     n++;
-     if (pd < (protonDeficit - deltapd))
-      pHa -= deltapH;
-     else if (pd > (protonDeficit + deltapd))
-      pHa += deltapH;
-     frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
-     protonDeficit = Acid * frac;
-     pd = ProtonDeficit(pHa);
-   }
-   //console.log('n: ' + n + ' pd: ' + pd + ' protonDeficit: ' + protonDeficit + ' frac: ' + frac + ' pHa: ' + pHa);
-   bicarbonate = wg_bicarbonate - protonDeficit * frac / liters;
-   total_alkalinity = bicarbonate * 50 / 61;
-   ph = pHa;
-   $('#wb_ph').val(Round(ph, 2));
-   $('#est_mash_ph').val(Round(ph, 2));
-  }
-
-  if ((AT == 3) && (liters > 0)) {        // Sulfuric / Zwavelzuur
-   RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 +
-        parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 +
-        Acidmg / 1000 * MMSO4 / (MMSO4 + 2);
-   RA = 1000 * RA / liters;
-   sulfate = wg_sulfate + RA;      // Not add to sulfate??
-  } else if ((AT == 1) && (liters > 0)) { // Hydrochloric, Zoutzuur
-   RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 +
-        parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl +
-        Acidmg / 1000 * MMCl / (MMCl + 1);
-   RA = 1000 * RA / liters;
-   chloride = wg_chloride + RA;
-  }
-
-  var BUGU = GetBUGU();
-  $('#tgt_bu').val(Round(BUGU, 2));
-  // From brouwhulp.
-  if (BUGU < 0.32)
-   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig en zoet</span>");
-  else if (BUGU < 0.43)
-   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig, zoet</span>");
-  else if (BUGU < 0.52)
-   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Evenwichtig</span>");
-  else if (BUGU < 0.63)
-   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht hoppig, bitter</span>");
-  else
-   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Extra hoppig, zeer bitter</span>");
-
-  // Sulfate to Chloride ratio (Palmer).
-  var OptSO4Clratio = GetOptSO4Clratio();
-  $('#tgt_so4_cl').val(Round(OptSO4Clratio, 1));
-  if (OptSO4Clratio < 0.4)
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Te moutig</span>");
-  else if (OptSO4Clratio < 0.6)
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig</span>");
-  else if (OptSO4Clratio < 0.8)
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig</span>");
-  else if (OptSO4Clratio < 1.5)
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Gebalanceerd</span>");
-  else if (OptSO4Clratio < 2.0)
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht bitter</span>");
-  else if (OptSO4Clratio < 4.0)
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Bitter</span>");
-  else if (OptSO4Clratio < 9.0)
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer bitter</span>");
-  else
-   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Te bitter</span>");
-  if (chloride > 0)
-   RA = sulfate / chloride;
-  else
-   RA = 10;
-  $('#got_so4_cl').val(Round(RA, 1));
-  Res = 'normaal';
-  if (RA < (0.8 * OptSO4Clratio))
-   Res = 'laag';
-  else if (RA > (1.2 * OptSO4Clratio))
-   Res = 'hoog';
-  setRangeIndicator('so4_cl', Res);
-
-  $('#wb_calcium').val(Round(calcium, 1));
-  $('#wb_magnesium').val(Round(magnesium, 1));
-  $('#wb_sodium').val(Round(sodium, 1));
-  $('#wb_sulfate').val(Round(sulfate, 1));
-  $('#wb_chloride').val(Round(chloride, 1));
-  $('#wb_bicarbonate').val(Round(bicarbonate, 1));
-  $('#wb_total_alkalinity').val(Round(total_alkalinity, 1));
-  $('#wb_hardness').val(Hardness(calcium, magnesium));
-  $('#wb_ra').val(ResidualAlkalinity(total_alkalinity, calcium, magnesium));
-
-  if (calcium < 40) {
-   setRangeIndicator('calcium', 'laag');
-  } else if (calcium > 150) {
-   setRangeIndicator('calcium', 'hoog');
-  } else {
-   setRangeIndicator('calcium', 'normaal');
-  }
-  if (magnesium < 5) {
-   setRangeIndicator('magnesium', 'laag');
-  } else if (magnesium > 40) {
-   setRangeIndicator('magnesium', 'hoog');
-  } else {
-   setRangeIndicator('magnesium', 'normaal');
-  }
-  if (sodium <= 150) {
-   setRangeIndicator('sodium', 'normaal');
-  } else {
-   setRangeIndicator('sodium', 'hoog');
-  }
-  // Both chloride and sulfate should be above 50 according to
-  // John Palmer. So the Cl/SO4 ratio calculation will work.
-  if (chloride <= 50) {
-   setRangeIndicator('chloride', 'laag');
-  } else if (chloride <= 150) {
-   setRangeIndicator('chloride', 'normaal');
-  } else {
-   setRangeIndicator('chloride', 'hoog');
-  }
-  if (sulfate <= 50) {
-   setRangeIndicator('sulfate', 'laag');
-  } else if (sulfate <= 400) {
-   setRangeIndicator('sulfate', 'normaal');
-  } else {
-   setRangeIndicator('sulfate', 'hoog');
-  }
-  // (cloride + sulfate) > 500 is too high
-  if ((chloride + sulfate) > 500) {
-   setRangeIndicator('chloride', 'hoog');
-   setRangeIndicator('sulfate', 'hoog');
-  }
-  if (ph < 5.2) {
-   setRangeIndicator('ph', 'laag');
-  } else if (ph > 5.6) {
-   setRangeIndicator('ph', 'hoog');
-  } else {
-   setRangeIndicator('ph', 'normaal');
-  }
-  if (bicarbonate > 250) {
-   setRangeIndicator('bicarbonate', 'hoog');
-  } else {
-   setRangeIndicator('bicarbonate', 'normaal');
-  }
-  calcSparge();
-  calcMiscs();
-  calcSupplies();
- }
-
- function calcSparge() {
-
-  /* Based on the work of ajDeLange. */
-  var ws_calcium, ws_magnesium, ws_total_alkalinity, ws_sodium, ws_chloride;
-  var ws_sulfate, ws_ph, ws_hardness, ws_ra;
-  var TargetpH = dataRecord.sparge_ph;
-  var Source_pH = 7.0;
-
-  // Select watersource or fallback to the first source.
-  if ((dataRecord.sparge_source == 1) && (dataRecord.w2_ph > 0.0)) { // Source 2
-    ws_calcium = dataRecord.w2_calcium;
-    ws_magnesium = dataRecord.w2_magnesium;
-    ws_total_alkalinity = dataRecord.w2_total_alkalinity;
-    ws_sodium = dataRecord.w2_sodium;
-    ws_chloride = dataRecord.w2_chloride;
-    ws_sulfate = dataRecord.w2_sulfate;
-    Source_pH = dataRecord.w2_ph;
-    $('#w2_button').jqxRadioButton({ checked: true });
-  } else if ((dataRecord.sparge_source == 2) && (dataRecord.w2_ph > 0.0)) { // Mixed
-    ws_calcium = dataRecord.wg_calcium;
-    ws_magnesium = dataRecord.wg_magnesium;
-    ws_total_alkalinity = dataRecord.wg_total_alkalinity;
-    ws_sodium = dataRecord.wg_sodium;
-    ws_chloride = dataRecord.wg_chloride;
-    ws_sulfate = dataRecord.wg_sulfate;
-    Source_pH = dataRecord.wg_ph;
-    $('#wg_button').jqxRadioButton({ checked: true });
-  } else {
-    ws_calcium = dataRecord.w1_calcium;
-    ws_magnesium = dataRecord.w1_magnesium;
-    ws_total_alkalinity = dataRecord.w1_total_alkalinity;
-    ws_sodium = dataRecord.w1_sodium;
-    ws_chloride = dataRecord.w1_chloride;
-    ws_sulfate = dataRecord.w1_sulfate;
-    Source_pH = dataRecord.w1_ph;
-    $('#w1_button').jqxRadioButton({ checked: true });
-  }
-
-  if (dataRecord.sparge_volume > 0) {
-   ws_calcium += (parseFloat($('#ss_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 +
-    parseFloat($('#ss_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000) / dataRecord.sparge_volume;
-   ws_magnesium += (parseFloat($('#ss_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4 * 1000 +
-    parseFloat($('#ss_mgcl2').jqxNumberInput('decimal')) * MMMg / MMMgCl2 * 1000) / dataRecord.sparge_volume;
-   ws_sodium += (parseFloat($('#ss_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000) / dataRecord.sparge_volume;
-   ws_sulfate += (parseFloat($('#ss_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 * 1000 +
-    parseFloat($('#ss_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 * 1000) / dataRecord.sparge_volume;
-   ws_chloride += (2 * parseFloat($('#ss_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 * 1000 +
-    parseFloat($('#ss_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl * 1000 +
-    parseFloat($('#ss_mgcl2').jqxNumberInput('decimal')) * MMCl / MMMgCl2 * 1000) / dataRecord.sparge_volume;
-  }
-
-  /* Show the spargewate with salt additions */
-  $('#sw_calcium').val(Round(ws_calcium, 1));
-  $('#sw_magnesium').val(Round(ws_magnesium, 1));
-  $('#sw_sodium').val(Round(ws_sodium, 1));
-  $('#sw_sulfate').val(Round(ws_sulfate, 1));
-  $('#sw_chloride').val(Round(ws_chloride, 1));
-  $('#sw_bicarbonate').val(Round(Bicarbonate(ws_total_alkalinity, Source_pH), 1));
-  $('#sw_total_alkalinity').val(Round(ws_total_alkalinity, 1));
-  $('#sw_ph').val(dataRecord.sparge_ph);
-  $('#sw_hardness').val(Hardness(ws_calcium, ws_magnesium));
-  $('#sw_ra').val(ResidualAlkalinity(ws_total_alkalinity, ws_calcium, ws_magnesium));
-
-  AT = dataRecord.sparge_acid_type;
-  if (AT < 0 || AT >= AcidTypeData.length) {
-   AT = 0;
-   dataRecord.sparge_acid_type = 0;
-   $('#sparge_acid_type').val(AcidTypeData[0].nl);
-   dataRecord.sparge_acid_perc = AcidTypeData[0].AcidPrc;
-   $('#sparge_acid_perc').val(dataRecord.sparge_acid_perc);
-  }
-
-  /*
-   * Auto calculate the required acid
-   */
-  if (dataRecord.calc_acid) {
-   // Step 1: Compute the mole fractions of carbonic (f1) and carbonate(f3) at the source water pH
-   var r1 = Math.pow(10, Source_pH - 6.35);
-   var r2 = Math.pow(10, Source_pH - 10.33);
-   var d = 1 + r1 + r1 * r2;
-   var f1 = 1 / d;
-   var f3 = r1 * r2 / d;
-
-   //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity)
-   var r143 = Math.pow(10, 4.3 - 6.35);
-   var r243 = Math.pow(10, 4.3 - 10.33);
-   var d43 = 1 + r143 + r143 * r243;
-   var f143 = 1 / d43;
-   var f343 = r143 * r243 / d43;
-
-   //Step 4. Solve
-   var Ct = ws_total_alkalinity / 50 / ((f143 - f1) + (f3 - f343));
-
-   //Step 5. Compute mole fractions at desired pH
-   var r1g = Math.pow(10, TargetpH - 6.35);
-   var r2g = Math.pow(10, TargetpH - 10.33);
-   var dg = 1 + r1g + r1g * r2g;
-   var f1g = 1 / dg;
-   var f3g = r1g * r2g / dg;
-
-   //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L)
-   var Acid = Ct * ((f1g - f1) + (f3 - f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH);  //mEq/l
-   Acid += 0.01;   // Add acid that would be required for distilled water.
-
-   //Step 8. Get the acid data.
-   var fract = CalcFrac(TargetpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
-
-   //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid.
-   Acid /= fract;
-
-   //Step 10. Multiply by molecular weight of the acid
-   Acid *= AcidTypeData[AT].MolWt; //mg
-
-   //Step 11. Divide by Specific Gravity and Percentage to get the final ml.
-   var RealSG = Round(((AcidTypeData[AT].AcidSG - 1000) * (dataRecord.sparge_acid_perc / 100)) + 1000, 2);
-   Acid = Acid / RealSG;           //ml
-   Acid *= dataRecord.sparge_volume; //ml acid total at 100%
-   Acid /= AcidTypeData[AT].AcidPrc / 100;     //ml acid at supplied strength
-   Acid = Round(Acid, 2);
-   dataRecord.sparge_acid_amount = Acid / 1000;
-   $('#sparge_acid_amount').val(Acid);
-  }
-
-  // Finally calculate the estimate preboil pH
-  var ph = -Math.log10(((Math.pow(10, -dataRecord.wb_ph) * dataRecord.wg_amount) + (Math.pow(10, -dataRecord.sparge_ph) * dataRecord.sparge_volume)) /
-          (dataRecord.wg_amount + dataRecord.sparge_volume));
-  $('#preboil_ph').val(ph);
- }
-
- function calcFermentation() {
-  var primary_svg, secondary_svg, final_svg, ABV;
-  if (dataRecord.brew_fermenter_sg < 1.020)
-   return;
-  if ((dataRecord.primary_end_sg > 0.990) && (dataRecord.primary_end_sg < dataRecord.brew_fermenter_sg)) {
-   primary_svg = Round(calc_svg(dataRecord.brew_fermenter_sg, dataRecord.primary_end_sg), 1);
-   $('#primary_svg').val(primary_svg);
-   if ((dataRecord.secondary_end_sg > 0.990) && (dataRecord.secondary_end_sg < dataRecord.brew_fermenter_sg)) {
-    secondary_svg = Round(calc_svg(dataRecord.brew_fermenter_sg, dataRecord.secondary_end_sg), 1);
-    $('#secondary_svg').val(secondary_svg);
-    if ((dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) {
-     final_svg = Round(calc_svg(dataRecord.brew_fermenter_sg, dataRecord.fg), 1);
-     $('#final_svg').val(final_svg);
-     ABV = Round(abvol(dataRecord.brew_fermenter_sg, dataRecord.fg), 2);
-     $('#final_abv').val(ABV);
-    }
-   }
-  }
- }
-
- function ResCO2(T) {
-  var F = T * 1.8 + 32;
-  return Round(3.0378 - 0.050062 * F + 0.00026555 * F * F, 6);
- }
-
- function CarbCO2toS(CO2, T, SFactor) {
-  //var sugar = SFactor * (CO2 - ResCO2(CO2, T)) / 0.286;
-  var sugar = Round(SFactor * (CO2 - ResCO2(T)) * 4.014094, 6);
-  if (sugar < 0)
-   sugar = 0;
-  return Round(sugar, 3);
- }
-
- function GetPressure(CO2, T1, T2) {
-  var P, V = CO2 - ResCO2(T1);
-  V = CO2; // TODO: temp only total pressure, testing
-  if (V < 0)
-   return 0;
-  P = -1.09145427669121 + 0.00800006989646477 * T2 + 0.000260276315484684 * T2 * T2 + 0.0215142075945119 * T2 * V +
-      0.674996600795854 * V + -0.00471757220150754 * V * V;
-  if (P < 0)
-   P = 0;
-  P = Round(P * 1.01325, 2); // atm to bar
-  console.log("GetPressure(" + CO2 + ", " + T1 + ", " + T2 + ")  V:" + V + "  Bar: " + P + " ignored ResCO2: " + ResCO2(T1));
-  return P;
- }
-
- function CarbCO2ToPressure(CO2, T) {
-  return (CO2 - (-0.000005594056 * Math.pow(T, 4) + 0.000144357886 * Math.pow(T, 3) +
-          0.000362999168 * T * T - 0.064872987645 * T + 1.641145175049)) /
-         (0.00000498031 * Math.pow(T, 4) - 0.00024358267 * Math.pow(T, 3) + 0.00385867329 * T * T - 0.05671206825 * T + 1.53801423376);
- }
-
- function calcCarbonation() {
-
-  var TSec, ABV, bvol, balc, babv, mvol, malc, tvol, talc, i, row, SFactor, pvol, pabv, Pressure, kabv;
-
-  console.log('calcCarbonation()');
-
-  TSec = dataRecord.secondary_temp;
-  if (TSec < 1)
-   TSec = dataRecord.primary_end_temp;
-  if (TSec < 1)
-   TSec = 18;
-
-  if (dataRecord.fg == 0.000)
-   ABV = abvol(dataRecord.brew_fermenter_sg, parseFloat($('#est_fg').jqxNumberInput('decimal')));
-  else
-   ABV = abvol(dataRecord.brew_fermenter_sg, dataRecord.fg);
-
-  /* Calculate new volume and alcohol. */
-  bvol = dataRecord.package_volume - (ABV * dataRecord.package_volume) / 100;
-  balc = dataRecord.package_volume - bvol;
-  mvol = dataRecord.package_infuse_amount - (dataRecord.package_infuse_abv * dataRecord.package_infuse_amount) / 100;
-  malc = dataRecord.package_infuse_amount - mvol;
-  talc = balc + malc;
-  tvol = bvol + mvol;
-  ABV = Round(talc / (tvol + talc) * 100, 2);
-  dataRecord.package_abv = ABV;
-  $('#package_abv').val(ABV);
-
-  //console.log("calcCarbonation() TSec:"+TSec+"  ABV:"+ABV);
-  if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) {
-   return;
-  }
-
-  // Bottles
-  dataRecord.bottle_priming_amount = 0;
-  dataRecord.bottle_priming_total = 0;
-  for (i = 0; i < rows.length; i++) {
-   row = rows[i];
-   if (row.f_added == 4) {
-    SFactor = 1 / ((row.f_yield / 100) * (1 - row.f_moisture / 100));
-    dataRecord.bottle_priming_amount = CarbCO2toS(dataRecord.bottle_carbonation, TSec, SFactor);
-    dataRecord.bottle_priming_total = Round(dataRecord.bottle_amount * dataRecord.bottle_priming_amount, 2);
-    $('#fermentableGrid').jqxGrid('setcellvalue', i, 'f_amount', dataRecord.bottle_priming_total / 1000);
-   }
-  }
-  $('#bottle_priming_amount').val(Round(dataRecord.bottle_priming_amount, 1));
-  $('#bottle_priming_total').val(dataRecord.bottle_priming_total);
-  pabv = ABV + dataRecord.bottle_priming_amount * 0.47 / 7.907;
-  pvol = dataRecord.bottle_amount - (pabv * dataRecord.bottle_amount) / 100;
-  talc = dataRecord.bottle_amount - pvol;
-  tvol = pvol + dataRecord.bottle_priming_water;
-  babv = Round(talc / (tvol + talc) * 100, 2);
-  //console.log("bottle pabv:"+pabv+" pvol:"+pvol+" wvol:"+dataRecord.bottle_priming_water+" tvol:"+tvol+" talc:"+talc+" abv:"+babv);
-  $('#bottle_abv').val(babv);
-  $('#bottle_pressure').val(GetPressure(dataRecord.bottle_carbonation, TSec, dataRecord.bottle_carbonation_temp));
-
-  // Kegs
-  Pressure = CarbCO2ToPressure(dataRecord.keg_carbonation, dataRecord.keg_carbonation_temp);
-  if (Pressure < 0)
-   Pressure = 0;
-  dataRecord.keg_pressure = Pressure;
-  $('#keg_pressure').val(Round(Pressure, 1));
-
-  dataRecord.keg_priming_amount = 0;
-  dataRecord.keg_priming_total = 0;
-  if (!dataRecord.keg_forced_carb) {
-   for (i = 0; i < rows.length; i++) {
-    row = rows[i];
-    if (row.f_added == 5) {
-     SFactor = 1 / ((row.f_yield / 100) * (1 - row.f_moisture / 100));
-     dataRecord.keg_priming_amount = CarbCO2toS(dataRecord.keg_carbonation, TSec, SFactor);
-     dataRecord.keg_priming_total = Round(dataRecord.keg_amount * dataRecord.keg_priming_amount, 2);
-     $('#fermentableGrid').jqxGrid('setcellvalue', i, 'f_amount', dataRecord.keg_priming_total / 1000);
-    }
-   }
-   $('#keg_priming_amount').val(Round(dataRecord.keg_priming_amount, 1));
-   $('#keg_priming_total').val(dataRecord.keg_priming_total);
-   pabv = ABV + dataRecord.keg_priming_amount * 0.47 / 7.907;
-   pvol = dataRecord.keg_amount - (pabv * dataRecord.keg_amount) / 100;
-   talc = dataRecord.keg_amount - pvol;
-   tvol = pvol + dataRecord.keg_priming_water;
-   kabv = Round(talc / (tvol + talc) * 100, 2);
-   //console.log("kegs  pabv:"+pabv+" pvol:"+pvol+" wvol:"+dataRecord.keg_priming_water+" tvol:"+tvol+" talc:"+talc+" abv:"+kabv);
-   $('#keg_abv').val(kabv);
-  } else {
-   $('#keg_priming_amount').val(0);
-   $('#keg_priming_total').val(0);
-   $('#keg_abv').val(ABV);
-  }
- }
-
- function calcStage() {
-  /*
-   * Set stage and enable or disable parts of the screens.
-   */
-  $('#stage').val(StageData[dataRecord.stage].nl);
-
-  /*
-   * Enable or disable parts of the screens.
-   */
-  $('#jqxTabs').jqxTabs((dataRecord.stage < 1) ? 'disableAt':'enableAt', 8);   // Brewday tab
-  $('#jqxTabs').jqxTabs((dataRecord.stage > 2) ? 'enableAt':'disableAt', 9);   // Fermentation tab
-  $('#jqxTabs').jqxTabs((dataRecord.stage < 9) ? 'disableAt':'enableAt', 11); // Tasting tab
- }
-
-
- // initialize the input fields.
- // Tab 1, Algemeen
- $('#name').jqxTooltip({ content: 'De naam voor dit product.' });
- $('#code').jqxTooltip({ content: 'Product code nummer.' });
- $('#birth').jqxTooltip({ content: 'De ontwerp datum van dit product.' });
- $('#stage').jqxTooltip({ content: 'De productie fase van dit product.' });
- $('#divide_batch').jqxTooltip({ content: 'Het aantal extra gesplitste batches.' });
- $('#divide_type').jqxTooltip({ content: 'Het splitsing moment in het productie proces.' });
- $('#notes').jqxTooltip({ content: 'De uitgebreide opmerkingen over dit product.' });
- $('#type').jqxTooltip({ content: 'Het brouw type van dit recept.' });
- $('#efficiency').jqxTooltip({ content: 'Het rendement van maischen en koken.' });
- $('#batch_size').jqxTooltip({ content: 'Het volume van het gekoelde wort na het koken.' });
- $('#boil_time').jqxTooltip({ content: 'De kooktijd in minuten.' });
- $('#boil_size').jqxTooltip({ content: 'Het volume van het wort voor het koken.' });
- $('#st_guide').jqxTooltip({ content: 'De bierstijl gids voor dit recept.'});
- $('#st_name').jqxTooltip({ content: 'De bierstijl naam voor dit recept.'});
- $('#st_letter').jqxTooltip({ content: 'De bierstijl letter voor dit recept.'});
- $('#st_letter').jqxInput({ theme: theme, width: 90, height: 23 });
- $('#st_type').jqxTooltip({ content: 'Het bierstijl type.'});
- $('#st_category').jqxTooltip({ content: 'De Amerikaanse bierstijl categorie.'});
- $('#st_category_number').jqxTooltip({ content: 'De Amerikaanse bierstijl categorie sub nummer.'});
- $('#est_og').jqxTooltip({ content: 'Het begin SG wat je wilt bereiken. De moutstort wordt automatisch herberekend.' });
- $('#st_og_min').jqxTooltip({ content: 'Het minimum begin SG voor deze bierstijl.'});
- $('#st_og_max').jqxTooltip({ content: 'Het maximum begin SG voor deze bierstijl.'});
- $('#est_fg').jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
- $('#st_fg_min').jqxTooltip({ content: 'Het minimum eind SG voor deze bierstijl.'});
- $('#st_fg_max').jqxTooltip({ content: 'Het maximum eind SG voor deze bierstijl.'});
- $('#est_abv').jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' });
- $('#st_abv_min').jqxTooltip({ content: 'Het minimum alcohol volume % voor deze bierstijl.'});
- $('#st_abv_max').jqxTooltip({ content: 'Het maximum alcohol volume % voor deze bierstijl.'});
- $('#est_color').jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' });
- $('#st_color_min').jqxTooltip({ content: 'De minimum kleur voor deze bierstijl.'});
- $('#st_color_max').jqxTooltip({ content: 'De maximum kleur voor deze bierstijl.'});
- $('#est_ibu').jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' });
- $('#st_ibu_min').jqxTooltip({ content: 'De minimum bitterheid voor deze bierstijl.'});
- $('#st_ibu_max').jqxTooltip({ content: 'De maximum bitterheid voor deze bierstijl.'});
- $('#kcal').jqxTooltip({ content: 'Energie-inhoud in kcal/liter.' });
- $('#est_carb').jqxTooltip({ content: 'Koolzuur volume. Dit wordt automatisch berekend.' });
- $('#st_carb_min').jqxTooltip({ content: 'Het minimum koolzuur volume voor deze bierstijl.'});
- $('#st_carb_max').jqxTooltip({ content: 'Het maximum koolzuur volume voor deze bierstijl.'});
-
- $('#name').jqxInput({ theme: theme, width: 640, height: 23 });
- $('#code, #stage').jqxInput({ theme: theme, width: 100, height: 23 });
- $('#locked').jqxCheckBox({ theme: theme, width: 120, height: 23, disabled: true });
- $('#birth,#divide_batch,#divide_type').jqxInput({ theme: theme, width: 120, height: 23 });
- $('#notes').jqxInput({ theme: theme, width: 960, height: 100 });
- $('#type').jqxInput({ theme: theme, width: 180, height: 23 });
- $('#efficiency').jqxNumberInput(Show1dec);
- $('#batch_size').jqxNumberInput(Show1dec);
- $('#boil_time').jqxNumberInput(Show0dec);
- $('#boil_size').jqxNumberInput(Show2dec);
- $('#st_guide,#st_name,#st_type,#st_category').jqxInput({ theme: theme, width: 250, height: 23 });
- $('#est_og').jqxNumberInput(Show3dec);
- $('#est_fg').jqxNumberInput(Show3dec);
- $('#st_og_min,#st_og_max,#st_fg_min,#st_fg_max').jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true });
- $('#est_ibu,#est_color').jqxNumberInput(Show0dec);
- $('#color_method').jqxInput({ theme: theme, width: 180, height: 23 });
- $('#st_color_min,#st_color_max,#st_category_number,#st_ibu_min,#st_ibu_max,#kcal').jqxNumberInput(Smal0dec);
- $('#ibu_method').jqxInput({ theme: theme, width: 180, height: 23 });
- $('#est_abv,#st_abv_min,#st_abv_max,#est_carb,#st_carb_min,#st_carb_max').jqxNumberInput(Smal1dec);
-
- // Tab 2, Equipment
- $('#eq_name').jqxTooltip({ content: 'De naam van deze brouw apparatuur.' });
- $('#eq_boil_size').jqxTooltip({ content: 'Normaal kook volume in liters' });
- $('#eq_batch_size').jqxTooltip({ content: 'Berekende batch grootte in liters aan het eind van de kook.' });
- $('#eq_tun_volume').jqxTooltip({ content: 'Maisch ketel volume.' });
- $('#eq_top_up_water').jqxTooltip({ content: 'Extra water in het gistvat.' });
- $('#eq_trub_chiller_loss').jqxTooltip({ content: 'Standaard verlies bij het overbrengen naar het gistvat.' });
- $('#eq_evap_rate').jqxTooltip({ content: 'Verdamping in liters per uur.' });
- $('#eq_boil_time').jqxTooltip({ content: 'Normale kooktijd in minuten, 0 voor no-boil recepten.' });
- $('#eq_top_up_kettle').jqxTooltip({ content: 'Extra water toevoegen tijdens de kook.' });
- $('#eq_hop_utilization').jqxTooltip({ content: '100% voor kleine installaties, hoger voor grote brouwerijen.' });
- $('#eq_notes').jqxTooltip({ content: 'Opmerkingen over deze apparatuur.' });
- $('#eq_lauter_volume').jqxTooltip({ content: 'Filterkuip volume.' });
- $('#eq_lauter_deadspace').jqxTooltip({ content: 'Filterkuip verlies in liters.' });
- $('#eq_kettle_volume').jqxTooltip({ content: 'Kook ketel volume in liters.' });
- $('#eq_mash_volume').jqxTooltip({ content: 'Maisch water voor de eerste stap.' });
- $('#eq_mash_max').jqxTooltip({ content: 'De maximale moutstort in Kg.' });
- $('#eq_efficiency').jqxTooltip({ content: 'Gemiddeld brouwzaal rendement.' });
-
- $('#eq_name').jqxInput({ theme: theme, width: 250, height: 23 });
- $('#eq_evap_rate').jqxNumberInput(Show2dec);
- $('#eq_boil_time,#eq_hop_utilization').jqxNumberInput(Show0dec);
- $('#eq_notes').jqxInput({ theme: theme, width: 960, height: 200 });
- $('#eq_boil_size,#eq_batch_size,#eq_tun_volume,#eq_top_up_water,#eq_trub_chiller_loss,#eq_top_up_kettle').jqxNumberInput(Show1dec);
- $('#eq_lauter_volume,#eq_lauter_deadspace,#eq_kettle_volume,#eq_mash_volume,#eq_mash_max,#eq_efficiency').jqxNumberInput(Show1dec);
-
- // Tab 3, Fermentables
- $('#est_color2').jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' });
- $('#est_og2').jqxTooltip({ content: 'Het geschatte begin SG van dit product.' });
- $('#mash_kg').jqxTooltip({ content: 'Het gewicht van alle mouten in de maisch.' });
-
- $('#est_color2').jqxNumberInput(Show0dec);
- $('#est_og2,#mash_kg').jqxNumberInput(Show3dec);
-
- $('#perc_malts').jqxProgressBar({
-  width: 300, height: 23, theme: theme, showText: true, max: 120, animationDuration: 0,
-  colorRanges: [{ stop: 90, color: '#008C00' },{ stop: 100, color: '#EB7331' },{ stop: 120, color: '#FF0000' }],
-  renderText: function(text) { return (Math.round(parseInt(text) * 1.2)) + '%'; }
- });
- $('#perc_sugars').jqxProgressBar({
-  width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0,
-  colorRanges: [{ stop: 20, color: '#008C00' },{ stop: 50, color: '#FF0000' }],
-  renderText: function(text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; }
- });
- $('#perc_cara').jqxProgressBar({
-  width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0,
-  colorRanges: [{ stop: 25, color: '#008C00' },{ stop: 50, color: '#FF0000' }],
-  renderText: function(text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; }
- });
- $('#ferm_lintner').jqxProgressBar({
-  width: 300, height: 23, theme: theme, showText: true, max: 200, animationDuration: 0,
-  colorRanges: [{ stop: 30, color: '#FF0000' },{ stop: 40, color: '#EB7331' },{ stop: 200, color: '#008C00' }],
-  renderText: function(text) { return (parseInt(text) * 2) + ' lintner'; }
- });
-
- // Tab 4, Hops
- $('#est_ibu2').jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' });
- $('#est_ibu2').jqxNumberInput(Smal0dec);
- $('#hop_flavour').jqxProgressBar({
-  width: 300, height: 23, theme: theme, showText: true, animationDuration: 0,
-  colorRanges: [
-   { stop: 20, color: '#004D00' },
-   { stop: 40, color: '#008C00' },
-   { stop: 60, color: '#00BF00' },
-   { stop: 80, color: '#00FF00' },
-   { stop: 100, color: '#80FF80' }
-  ],
-  renderText: function(text) {
-   var val = parseInt(text);
-   if (val < 20)
-    return 'Weinig';
-   else if (val < 40)
-    return 'Matig';
-   else if (val < 60)
-    return 'Redelijk';
-   else if (val < 80)
-    return 'Veel';
-   else
-    return 'Zeer veel';
-   }
- });
- $('#hop_aroma').jqxProgressBar({
-  width: 300, height: 23, theme: theme, showText: true, animationDuration: 0,
-  colorRanges: [
-   { stop: 20, color: '#004D00' },
-   { stop: 40, color: '#008C00' },
-   { stop: 60, color: '#00BF00' },
-   { stop: 80, color: '#00FF00' },
-   { stop: 100, color: '#80FF80' }
-  ],
-  renderText: function(text) {
-   var val = parseInt(text);
-   if (val < 20)
-    return 'Weinig';
-   else if (val < 40)
-    return 'Matig';
-   else if (val < 60)
-    return 'Redelijk';
-   else if (val < 80)
-    return 'Veel';
-   else
-    return 'Zeer veel';
-  }
- });
-
- // Tab 5, Miscs
-
- // Tab 6, Yeasts
- $('#est_fg2').jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
- $('#est_abv2').jqxTooltip({ content: 'Verwacht alcohol volume %. Dit wordt automatisch berekend.' });
- $('#yeast_grams').jqxTooltip({ content: 'De gewenste totale hoeveelheid droge gist voor dit bier.' });
- $('#yeast_gr_hl').jqxTooltip({ content: 'De werkelijke hoeveelheid gist per hectoliter.' });
- $('#yeast_cells').jqxTooltip({ content: 'Het aantal miljard beschikbare gistcellen zonder eventuele starter.' });
- $('#need_cells').jqxTooltip({ content: 'Het aantal miljard nodige cellen is afhankelijk van het begin SG, biertype en volume.' });
- $('#plato_cells').jqxTooltip({ content: 'De berekende pitchrate in miljard cellen per ml per graad Plato.' });
- $('#yeast_prod_date').jqxTooltip({ content: 'Bij korrelgisten is meestal "best voor" datum op het zakje gedrukt.<br>Gebruik die datum maar dan twee jaar eerder als productie datum.<br>Bij White Labs is de productie datum vier maanden voor de "Best by" datum die geprint op het buisje.<br>Bij Wyeast is dit de "manufacture date" die op het pak geprint is.<br>Voor schuine buis, slurry, opkweek en gedroogd is dit de datum dat je de gist geoogst hebt.' });
- $('#yeast_pitchrate').jqxTooltip({ content: 'De gewenste pitchrate in miljard cellen per ml per graad Plato voor de vergisting van dit bier.' });
-
- $('#est_fg2,#plato_cells').jqxNumberInput(Show3dec);
- $('#est_fg2').jqxNumberInput({ width: 70 });
- $('#est_abv2').jqxNumberInput(Show2dec);
- $('#est_abv2').jqxNumberInput({ width: 70, symbol: '%', symbolPosition: 'right' });
- $('#yeast_grams').jqxNumberInput(Show1dec);
- $('#yeast_gr_hl').jqxNumberInput(Show1dec);
- $('#yeast_cells,#need_cells').jqxNumberInput(Show1dec);
- $('#yeast_prod_date').jqxDateTimeInput(Dateopts);
- $('#yeast_prod_date').jqxDateTimeInput({ disabled: true });
- $('#yeast_pitchrate').jqxNumberInput(Show3dec);
- for (i = 1; i < 5; i++) {
-  $('#prop' + i + '_volume').jqxTooltip({ content: 'Het volume van deze starter stap.' });
-  $('#prop' + i + '_irate').jqxTooltip({ content: 'Voor de beste gistgroei, houd de injectie factor tussen de 25 en 100 miljoen cellen per ml.' });
-  $('#prop' + i + '_ncells').jqxTooltip({ content: 'Het aantal miljard nieuwe gistcellen in deze stap.' });
-  $('#prop' + i + '_tcells').jqxTooltip({ content: 'Het totaal aantal miljard gistcellen na deze stap.' });
-  $('#prop' + i + '_growf').jqxTooltip({ content: 'De groeifactor, minstens 1. Ongeroerde starters komen meestal niet boven de 3.' });
-
-  $('#prop' + i + '_type').jqxInput({ theme: theme, width: 120, height: 23 });
-  $('#prop' + i + '_volume').jqxNumberInput(Show3dec);
-  $('#prop' + i + '_irate,#prop' + i + '_ncells,#prop' + i + '_tcells').jqxNumberInput(Show1dec);
-  $('#prop' + i + '_growf').jqxNumberInput(Show2dec);
-  $('#prop' + i + '_type,#prop' + i + '_volume,#prop' + i + '_irate,#prop' + i + '_ncells,#prop' + i + '_tcells,#prop' + i + '_growf').hide();
- }
- $('#starter_type').jqxInput({ theme: theme, width: 120, height: 23 });
- $('#starter_sg').jqxTooltip({ content: 'Het ideale starter SG moet tussen de 1.030 en 1.040 zijn. Optimaal is 1.037.' });
- $('#starter_sg').jqxNumberInput(Show3dec);
- $('#starter_viability').jqxTooltip({ content: 'De gist conditie.' });
- $('#starter_viability').jqxNumberInput(Show0dec);
-
- // Tab 7, Mashing
- $('#mash_name').jqxTooltip({ content: 'De omschrijving van dit maisch profiel.' });
- $('#mash_name').jqxInput({ theme: theme, width: 320, height: 23 });
- $('#est_mashvol').jqxTooltip({ content: 'Het totale volume van het maishwater en de mout in de maish pan.' });
- $('#est_mashvol').jqxNumberInput(Show1dec);
- $('#est_mashtime').jqxTooltip({ content: 'De totale tijdsduur van het maischen.' });
- $('#est_mashtime').jqxInput({ theme: theme, width: 70, height: 23 });
-
- // Tab 8, Water
- $('#tgt_bu').jqxNumberInput(Show2wat);
- $('#tgt_so4_cl,#got_so4_cl').jqxNumberInput(Show1wat);
- $('#preboil_ph').jqxNumberInput(Show2wat);
-
- // Water source 1
- $('#w1_name').jqxInput({ theme: theme, width: 200, height: 23 });
- $('#w1_button').jqxRadioButton({ theme: theme, width: 50, height: 23, disabled: true });
- $('#w1_amount,#w1_calcium,#w1_magnesium,#w1_sodium,#w1_bicarbonate,#w1_total_alkalinity,#w1_chloride,#w1_sulfate').jqxNumberInput(Show1wat);
- $('#w1_ph').jqxNumberInput(Show2wat);
- $('#w1_hardness').jqxNumberInput(Show1wat);
- $('#w1_ra').jqxNumberInput(Show1wat);
- // Water source 2
- $('#w2_name').jqxInput({ theme: theme, width: 200, height: 23 });
- $('#w2_button').jqxRadioButton({ theme: theme, width: 50, height: 23, disabled: true });
- $('#w2_amount').jqxNumberInput(Show1wat);
- $('#w2_calcium,#w2_magnesium,#w2_sodium,#w2_bicarbonate,#w2_total_alkalinity,#w2_chloride,#w2_sulfate').jqxNumberInput(Show1wat);
- $('#w2_ph').jqxNumberInput(Show2wat);
- $('#w2_hardness').jqxNumberInput(Show1wat);
- $('#w2_ra').jqxNumberInput(Show1wat);
- // Water mixed
- $('#wg_button').jqxRadioButton({ theme: theme, width: 50, height: 23, disabled: true });
- $('#wg_amount,#wg_calcium,#wg_magnesium,#wg_sodium,#wg_bicarbonate,#wg_total_alkalinity,#wg_chloride,#wg_sulfate').jqxNumberInput(Show1wat);
- $('#wg_ph').jqxNumberInput(Show2wat);
- $('#wg_hardness').jqxNumberInput(Show1wat);
- $('#wg_ra').jqxNumberInput(Show1wat);
- // Water treated
- $('#wb_calcium').jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'});
- $('#wb_calcium').jqxNumberInput(Show1wat);
- $('#wb_magnesium').jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is tussen 5 en 40.'});
- $('#wb_magnesium').jqxNumberInput(Show1wat);
- $('#wb_sodium').jqxTooltip({ content: 'De ideale hoeveelheid Natrium is lager dan 150.'});
- $('#wb_sodium').jqxNumberInput(Show1wat);
- $('#wb_chloride').jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 150. Samen met Sulfaat minder dan 500.'});
- $('#wb_chloride').jqxNumberInput(Show1wat);
- $('#wb_sulfate').jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 400. Samen met Chloride minder dan 500.'});
- $('#wb_sulfate').jqxNumberInput(Show1wat);
- $('#wb_bicarbonate').jqxTooltip({ content: '0 tot 50 lichte bieren, 50 tot 150 amber bieren, 150 tot 250 donkere bieren.'});
- $('#wb_bicarbonate').jqxNumberInput(Show1wat);
- $('#wb_ph').jqxNumberInput(Show2wat);
- $('#wb_hardness').jqxNumberInput(Show1wat);
- $('#wb_ra').jqxNumberInput(Show1wat);
- // Sparge water
- $('#sw_amount').jqxNumberInput(Show1wat);
- $('#sw_calcium').jqxNumberInput(Show1wat);
- $('#sw_magnesium').jqxNumberInput(Show1wat);
- $('#sw_sodium').jqxNumberInput(Show1wat);
- $('#sw_bicarbonate').jqxNumberInput(Show1wat);
- $('#sw_total_alkalinity').jqxNumberInput(Show1wat);
- $('#sw_chloride').jqxNumberInput(Show1wat);
- $('#sw_sulfate').jqxNumberInput(Show1wat);
- $('#sw_ph').jqxNumberInput(Show2wat);
- $('#sw_hardness').jqxNumberInput(Show1wat);
- $('#sw_ra').jqxNumberInput(Show1wat);
-
- // Water agents
- $('#wa_cacl2').jqxTooltip({ content: 'Voor het maken van een ander waterprofiel. Voegt calcium en chloride toe. Voor het verbeteren van zoetere bieren.' });
- $('#wa_cacl2').jqxNumberInput(Show2wat);
- $('#ss_cacl2').jqxNumberInput(Show2wat);
-
- $('#wa_caso4').jqxTooltip({
-  content: 'Gips. Voor het maken van een ander waterprofiel. Voegt calcium en sulfaat toe. Voor het verbeteren van bittere bieren.'
- });
- $('#wa_caso4').jqxNumberInput(Show2wat);
- $('#ss_caso4').jqxNumberInput(Show2wat);
-
- $('#wa_mgso4').jqxTooltip({ content: 'Epsom zout. Voor het maken van een ander waterprofiel. Voegt magnesium en sulfaat toe. Gebruik spaarzaam!' });
- $('#wa_mgso4').jqxNumberInput(Show2wat);
- $('#ss_mgso4').jqxNumberInput(Show2wat);
-
- $('#wa_nacl').jqxTooltip({
-  content: 'Keukenzout. Voor het maken van een ander waterprofiel. Voegt natrium en chloride toe. ' +
-  'Voor het accentueren van zoetheid. Bij hoge dosering wordt het bier ziltig.'
- });
- $('#wa_nacl').jqxNumberInput(Show2wat);
- $('#ss_nacl').jqxNumberInput(Show2wat);
-
- $('#wa_mgcl2').jqxTooltip({ content: 'Magnesiumchloride'});
- $('#wa_mgcl2').jqxNumberInput(Show2wat);
- $('#ss_mgcl2').jqxNumberInput(Show2wat);
-
- $('#wa_nahco3').jqxTooltip({ content: 'Baksoda'});
- $('#wa_caco3').jqxTooltip({ content: 'Kalk'});
- $('#wa_nahco3,#wa_caco3').jqxNumberInput(Show2wat);
-
- $('#mash_ph').jqxTooltip({ content: 'Maisch pH tussen 5.2 en 5.6. Gebruik 5.2 voor lichte en 5.5 voor donkere bieren.'});
- $('#mash_ph').jqxNumberInput(Show2dec);
-
- $('#calc_acid').jqxCheckBox({ theme: theme, width: 120, height: 23, disabled: true });
-
- $('#wa_acid_name').jqxInput({ theme: theme, width: 130, height: 23 });
- $('#wa_acid').jqxNumberInput(Show2dec);
- $('#wa_acid').jqxNumberInput({ symbol: ' ml', symbolPosition: 'right' });
- $('#wa_acid_perc').jqxNumberInput(Show0dec);
- $('#wa_acid_perc').jqxNumberInput({ symbol: '%', symbolPosition: 'right' });
-
- // Sparge water
- $('#sparge_ph').jqxNumberInput(Show2dec);
- $('#sparge_acid_amount').jqxNumberInput(Show2dec);
- $('#sparge_acid_amount').jqxNumberInput({ symbol: ' ml', symbolPosition: 'right' });
- $('#sparge_acid_type').jqxInput({ theme: theme, width: 130, height: 23 });
- $('#sparge_acid_perc').jqxNumberInput(Show0dec);
- $('#sparge_acid_perc').jqxNumberInput({ symbol: '%', symbolPosition: 'right' });
-
- // Tab 9, Brewday
- $('#brew_date_start').jqxTooltip({ content: 'Brouw datum en tijd. Voor planning laat de tijd op 00:00:00 staan.' });
- $('#brew_date_end').jqxTooltip({ content: 'End datum en tijd van de brouw. Leeg laten als er nog niet gebrouwen is.' });
- $('#brew_mash_ph').jqxTooltip({ content: 'De gemeten pH tijdens het maischen eventueel na correctie.' });
- $('#est_mash_ph').jqxTooltip({ content: 'De gewenste pH tijdens het maischen.' });
- $('#brew_preboil_ph').jqxTooltip({ content: 'De gemeten pH in de kookketel na het spoelen en voor de kook.' });
- $('#brew_aboil_ph').jqxTooltip({ content: 'De gemeten pH na het koken.' });
- $('#brew_mash_sg').jqxTooltip({ content: 'Het bereikte SG na het maischen.' });
- $('#est_mash_sg').jqxTooltip({ content: 'Het berekende verwachte SG na het maischen.' });
- $('#brew_preboil_sg').jqxTooltip({ content: 'Het gemeten SG in de kookketel na het spoelen en voor het koken.' });
- $('#est_pre_sg').jqxTooltip({ content: 'Het berekende SG in de kookketel na het spoelen en voor het koken.' });
- $('#brew_aboil_sg').jqxTooltip({ content: 'Het gemeten SG in de kookketel na het koken.' });
- $('#est_og3').jqxTooltip({ content: 'Het gewenste SG in de kookketel na het koken zonder eventuele suikers die tijdens de vergisting toegevoegd worden.' });
- $('#brew_mash_efficiency').jqxTooltip({ content: 'Het behaalde maisch rendement.' });
- $('#brew_preboil_volume').jqxTooltip({ content: 'Het gemeten volume van het wort voor het koken.' });
- $('#est_pre_vol').jqxTooltip({ content: 'Het berekende volume van het wort voor het koken.' });
- $('#brew_aboil_volume').jqxTooltip({ content: 'Het gemeten volume van het wort na het koken.' });
- $('#est_a_vol').jqxTooltip({ content: 'Het gewenste volume na het koken.' });
- $('#brew_preboil_efficiency').jqxTooltip({ content: 'Het berekende rendement voor het koken.' });
- $('#brew_aboil_efficiency').jqxTooltip({ content: 'Het bereikte rendement na het koken.' });
- $('#brew_sparge_temperature').jqxTooltip({ content: 'De spoelwater temperatuur, in te stellen in de Water tab.' });
- $('#brew_sparge_volume').jqxTooltip({ content: 'Het spoelwater voorraad volume, in te stellen in de Water tab.' });
- $('#brew_date_start,#brew_date_end').jqxDateTimeInput(DateTimeopts);
- $('#brew_date_start,#brew_date_end').jqxDateTimeInput({ disabled: true });
- $('#est_mash_ph').jqxNumberInput(Show2wat);
- $('#brew_mash_ph,#brew_preboil_ph,#brew_aboil_ph').jqxNumberInput(Show2dec);
- $('#brew_mash_sg,#brew_preboil_sg,#brew_aboil_sg').jqxNumberInput(Show3dec);
- $('#est_mash_sg,#est_pre_sg,#est_og3').jqxNumberInput(Show3wat);
- $('#brew_mash_efficiency').jqxNumberInput(Show1dec);
- $('#brew_preboil_volume,#brew_aboil_volume').jqxNumberInput(Show1dec);
- $('#ketel_volume').jqxNumberInput(Show1dec);
- $('#ketel_cm').jqxNumberInput(Show1dec);
- $('#est_pre_vol,#est_a_vol').jqxNumberInput(Show1wat);
- $('#brew_preboil_efficiency,#brew_aboil_efficiency,#brew_sparge_temperature,#brew_sparge_volume,#brew_sparge_est').jqxNumberInput(Show1dec);
- $('#brew_cooling_to').jqxNumberInput(Show1dec);
- $('#brew_sparge_ph').jqxNumberInput(Show2dec);
- $('#brew_cooling_method').jqxInput({ theme: theme, width: 180, height: 23 });
- $('#brew_cooling_time,#brew_whirlpool9,#brew_whirlpool7,#brew_whirlpool6,#brew_whirlpool2,#brew_aeration_time,#brew_aeration_speed').jqxNumberInput(Show0dec);
- $('#brew_aeration_type').jqxInput({ theme: theme, width: 180, height: 23 });
- $('#brew_fermenter_volume').jqxNumberInput(Show1dec);
- $('#brew_fermenter_sg').jqxNumberInput(Show3dec);
- $('#brew_fermenter_extrawater,#brew_fermenter_tcloss').jqxNumberInput(Show1dec);
- $('#brew_fermenter_ibu,#brew_fermenter_color').jqxNumberInput(Show0dec);
-
- // Tab 10, Fermentation
- $('#brew_fermenter_sg2').jqxTooltip({ content: 'Het behaalde SG in het gistvat, overgenomen van de brouwdag.' });
- $('#primary_start_temp').jqxTooltip({ content: 'De begintemperatuur van de hoofdvergisting.' });
- $('#primary_max_temp').jqxTooltip({ content: 'De hoogst bereikte piek temperatuur tijdens de hoofgvergisting.' });
- $('#primary_end_temp').jqxTooltip({ content: 'De eind temperatuur van de hoofdvergisting.' });
- $('#primary_end_sg').jqxTooltip({ content: 'Het gemeten SG aan het eind van de hoofdvergisting.' });
- $('#primary_svg').jqxTooltip({ content: 'De schijnbare vergisting graad behaald na de hoofdgisting.' });
- $('#primary_end_date').jqxTooltip({ content: 'De eind datum van de hoofdvergisting en eventueel overhevelen.' });
- $('#secondary_end_sg').jqxTooltip({ content: 'Het gemeten SG aan het eind van de navergisting.' });
- $('#secondary_svg').jqxTooltip({ content: 'De schijnbare vergisting graad behaald na de nagisting.' });
- $('#secondary_end_date').jqxTooltip({ content: 'De eind datum van de navergisting en het begin van het lageren.' });
- $('#est_fg3').jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
-
- $('#primary_end_sg,#secondary_end_sg').jqxNumberInput(Show3dec);
- $('#primary_end_date,#secondary_end_date').jqxDateTimeInput(Dateopts);
- $('#primary_end_date,#secondary_end_date').jqxDateTimeInput({ disabled: true });
- $('#primary_start_temp,#primary_max_temp,#primary_end_temp,#secondary_temp,#tertiary_temp').jqxNumberInput(Show1dec);
- $('#fg').jqxNumberInput(Show3dec);
- $('#brew_fermenter_sg2,#est_fg3').jqxNumberInput(Show3dec);
- $('#final_abv').jqxNumberInput(Show2dec);
- $('#primary_svg,#secondary_svg,#final_svg').jqxNumberInput(Show1dec);
- $('#FLog').jqxButton({ template: 'info', width: '150px', theme: theme });
- $('#FLog').click(function() {
-  // Open log in a new tab.
-  window.open('log_fermentation.php?code=' + dataRecord.code + '&name=' + dataRecord.name);
- });
- $('#ILog').jqxButton({ template: 'info', width: '150px', theme: theme });
- $('#ILog').click(function() {
-  // Open log in a new tab.
-  window.open('log_ispindel.php?code=' + dataRecord.code + '&name=' + dataRecord.name);
- });
-
- // Tab 11, Packaging
- // TODO: high gravity packaging, extra water and recalc abv, color and ibu.
- $('#package_date').jqxTooltip({ content: 'De verpakkings datum van dit bier.' });
- $('#package_volume').jqxTooltip({ content: 'Het beschikbare volume om te bottelen of op fust te zetten.' });
- $('#package_infuse_amount').jqxTooltip({ content: 'De hoeveelheid water of drank extra toe te voegen.' });
- $('#package_infuse_abv').jqxTooltip({ content: 'De hoeveelheid alcohol in de drank, of 0.0 als het water is.' });
- $('#package_infuse_notes').jqxTooltip({ content: 'Omschrijving van de extra toevoeging.' });
- $('#package_abv').jqxTooltip({ content: 'De uiteindelijke hoeveelheid alcohol volume %.' });
- $('#package_ph').jqxTooltip({ content: 'De gemeten pH vlak voor het verpakken.' });
- $('#st_carb_min2').jqxTooltip({ content: 'Het minimum aanbevolen koolzuur volume voor deze bierstijl.'});
- $('#st_carb_max2').jqxTooltip({ content: 'Het maximum aamnevolen koolzuur volume voor deze bierstijl.'});
- $('#bottle_amount').jqxTooltip({ content: 'De totale hoeveelheid te bottelen bier.' });
- $('#keg_amount').jqxTooltip({ content: 'De totale hoeveelheid op fust te zetten bier.' });
- $('#bottle_carbonation').jqxTooltip({ content: 'Het gewenste CO2 volume in de flessen.' });
- $('#keg_carbonation').jqxTooltip({ content: 'Het gewenste CO2 volume door de suiker in de fusten.' });
- $('#bottle_priming_water,#keg_priming_water').jqxTooltip({ content: 'De hoeveelheid water om de suiker op te lossen.' });
- $('#bottle_pressure').jqxTooltip({ content: 'De maximaal te verwachten druk tijdens het hergisten.' });
- $('#package_date').jqxDateTimeInput(Dateopts);
- $('#package_date').jqxDateTimeInput({ disabled: true });
- $('#package_infuse_amount').jqxNumberInput(Show3dec);
- $('#package_infuse_notes').jqxInput({ theme: theme, width: 640, height: 23 });
- $('#package_abv').jqxNumberInput(Show2dec);
- $('#package_ph').jqxNumberInput(Show2dec);
- $('#st_carb_min2,#st_carb_max2').jqxNumberInput(Smal1dec);
- $('#package_volume,#package_infuse_abv,#bottle_amount,#keg_amount').jqxNumberInput(Show1dec);
- $('#bottle_carbonation,#keg_carbonation').jqxNumberInput(Show2dec);
- $('#bottle_priming_sugar').jqxInput({ theme: theme, width: 200, height: 23 });
- $('#keg_priming_sugar').jqxInput({ theme: theme, width: 200, height: 23 });
- $('#bottle_priming_water,#keg_priming_water').jqxNumberInput(Show3dec);
- $('#keg_forced_carb').jqxCheckBox({ theme: theme, width: 120, height: 23, disabled: true });
- $('#bottle_priming_amount,#keg_priming_amount,#bottle_priming_total,#bottle_pressure,#keg_priming_total,#keg_pressure').jqxNumberInput(Show1dec);
- $('#bottle_abv,#keg_abv').jqxNumberInput(Show2dec);
- $('#bottle_carbonation_temp,#keg_carbonation_temp').jqxNumberInput(Show1dec);
- $('#CLog').jqxButton({ template: 'info', width: '150px', theme: theme });
- $('#CLog').click(function() {
-  // Open log in a new tab.
-  window.open('log_co2pressure.php?code=' + dataRecord.code + '&name=' + dataRecord.name);
- });
-
- // Tab 12, Tasting
- $('#taste_date').jqxTooltip({ content: 'De proef datum van dit bier.' });
- $('#taste_date').jqxDateTimeInput(Dateopts);
- $('#taste_date').jqxDateTimeInput({ disabled: true });
- $('#taste_rate').jqxTooltip({ content: 'Het cijfer voor dit bier van 1 tot 10.' });
- $('#taste_rate').jqxNumberInput(Show1dec);
- $('#taste_color').jqxTooltip({ content: 'De kleur van het bier.' });
- $('#taste_transparency').jqxTooltip({ content: 'De helderheid van het bier.' });
- $('#taste_head').jqxTooltip({ content: 'Het schuim op het bier.' });
- $('#taste_color,#taste_transparency,#taste_head').jqxInput({ theme: theme, width: 320, height: 23 });
- $('#taste_aroma').jqxTooltip({ content: 'Het aroma van het bier.' });
- $('#taste_taste').jqxTooltip({ content: 'De smaak van het bier.' });
- $('#taste_aftertaste').jqxTooltip({ content: 'De nasmaak van het bier.' });
- $('#taste_mouthfeel').jqxTooltip({ content: 'Het mondgevoelvan het bier.' });
- $('#taste_aroma,#taste_taste,#taste_aftertaste,#taste_mouthfeel').jqxInput({ theme: theme, width: 960, height: 23 });
- $('#taste_notes').jqxTooltip({ content: 'Het oordeel en opmerkingen over dit bier.' });
- $('#taste_notes').jqxInput({ theme: theme, width: 960, height: 100 });
-
- $('#jqxTabs').jqxTabs({
-  theme: theme,
-  width: 1280,
-  height: 660,
-  autoHeight: false,
-  position: 'top'
- });
-
- // Buttons below
- $('#Terug').jqxButton({ template: 'primary', width: '80px', theme: theme });
- $('#Terug').bind('click', function() {
-  window.location.href = my_return;
- });
-});
-
--- a/www/js/prod_inprod.js	Sat Aug 06 22:02:42 2022 +0200
+++ b/www/js/prod_inprod.js	Sat Aug 06 22:10:28 2022 +0200
@@ -80,10 +80,10 @@
     }
    },
    { text: '', datafield: 'Edit', width: 100, align: 'center', columntype: 'button', cellsrenderer: function() {
-    return 'Wijzig';
+    return 'Bekijk';
     }, buttonclick: function(row) {
      var datarecord = dataAdapter.records[row];
-     window.location.href = 'prod_edit.php?record=' + datarecord.record + '&select=inprod&return=prod_inprod.php';
+     window.location.href = 'prod_view.php?record=' + datarecord.record + '&select=inprod&return=prod_inprod.php';
     }
    }
   ],
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/www/js/prod_view.js	Sat Aug 06 22:10:28 2022 +0200
@@ -0,0 +1,3306 @@
+/*****************************************************************************
+ * Copyright (C) 2018-2022
+ *
+ * Michiel Broek <mbroek at mbse dot eu>
+ *
+ * This file is part of BMS
+ *
+ * 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.
+ *****************************************************************************/
+
+
+function block_fermentable(stage, added) {
+ if (stage > 5 && added < 4) // After fermentation and added before packaging
+  return true;
+ if (stage > 3 && added < 3) // After primary and added before sec/tert
+  return true;
+ if (stage > 2 && added < 2) // After boil and added during mash or boil
+  return true;
+ return false;
+}
+
+function block_hop(stage, useat)
+{
+ if (stage > 2 && useat < 5)
+  return true;
+ return false;
+}
+
+function block_misc(stage, use_use) {
+ if (stage > 5 && use_use < 5)
+  return true;
+ if (stage > 3 && use_use < 4)
+  return true;
+ if (stage > 2 && use_use < 3)
+  return true;
+ if (stage > 1 && use_use < 1)
+  return true;
+ return false;
+}
+
+function block_yeast(stage, use) {
+ if (stage > 3 && use < 1)
+  return true;
+ if (stage > 4 && use < 2)
+  return true;
+ if (stage > 5 && use < 3)
+  return true;
+ if (stage > 6 && use < 4)
+  return true;
+ return false;
+}
+
+
+$(document).ready(function() {
+
+ var i,
+ to_100 = false,      // Fermentables adjust to 100%
+ preboil_sg = 0,
+ aboil_sg = 0,
+ est_mash_sg = 0,
+ psugar = 0,          // Percentage real sugars
+ pcara = 0,           // Percentage cara/crystal malts
+ svg = 77,            // Default attenuation
+ mashkg = 0,          // Malt in mash weight
+ initcells = 0,       // Initial yeast cell count
+
+ ok_fermentables = 1, // Fermentables are in stock
+ ok_hops = 1,         // Hops are in stock
+ ok_miscs = 1,        // Miscs are in stock
+ ok_yeasts = 1,       // Yeasts are in stock
+ ok_waters = 1,       // Waters are in stock
+
+ data_loaded = 0;
+ error_count = 0;
+ k_cm = 0;
+ k_vol = 0;
+ k_what = 0;
+
+ hop_flavour = 0,
+ hop_aroma = 0,
+ mash_infuse = 0,
+ last_acid = '',
+
+ MMCa = 40.048,
+ MMMg = 24.305,
+ MMNa = 22.98976928,
+ MMCl = 35.453,
+ MMSO4 = 96.0626,
+ MMHCO3 = 61.01684,
+ MMCaSO4 = 172.171,
+ MMCaCl2 = 147.015,
+ MMCaCO3 = 100.087,
+ MMMgCl2 = 95.211,	/* Since 27-06-2021 */
+ MMMgSO4 = 246.475,
+ MMNaHCO3 = 84.007,
+ MMNa2CO3 = 105.996,
+ MMNaCl = 58.443,
+ MMCaOH2 = 74.06268,
+
+ fermentableRow = 0,
+ fermentableData = {},
+ fermentableInit = 1,
+ hopRow = 0,
+ hopData = {},
+ miscRow = 0,
+ miscData = {},
+ yeastRow = 0,
+ yeastData = {},
+ mashRow = 0,
+ mashData = {},
+ Ka1 = 0.0000004445,
+ Ka2 = 0.0000000000468,
+ dataRecord = {},
+ url = 'includes/db_product.php',
+ MaltVolume = 0.87,    // l/kg 0.688 volgens internetbronnen, gemeten 0.874 l/kg, na enige tijd maischen 0,715 l/kg (A3 Otten).
+ SpecificHeatWater = 1.0,
+ SpecificHeatMalt = 0.399, //cal/g.°C
+ SlakingHeat = 10.318, //cal/g.°C
+
+ // Prepare the data
+ source = {
+  datatype: 'json',
+  cache: false,
+  async: true,
+  datafields: [
+   // From prod_main
+   { name: 'record', type: 'number' },
+   { name: 'uuid', type: 'string' },
+   { name: 'name', type: 'string' },
+   { name: 'code', type: 'string' },
+   { name: 'birth', type: 'string' },
+   { name: 'stage', type: 'int' },
+   { name: 'notes', type: 'string' },
+   { name: 'log_brew', type: 'int' },
+   { name: 'log_fermentation', type: 'int' },
+   { name: 'log_ispindel', type: 'int' },
+   { name: 'log_co2pressure', type: 'int' },
+   { name: 'inventory_reduced', type: 'int' },
+   { name: 'locked', type: 'int' },
+   { name: 'eq_name', type: 'string' },
+   { name: 'eq_boil_size', type: 'float' },
+   { name: 'eq_batch_size', type: 'float' },
+   { name: 'eq_tun_volume', type: 'float' },
+   { name: 'eq_tun_weight', type: 'float' },
+   { name: 'eq_tun_specific_heat', type: 'float' },
+   { name: 'eq_tun_material', type: 'int' },
+   { name: 'eq_tun_height', type: 'float' },
+   { name: 'eq_top_up_water', type: 'float' },
+   { name: 'eq_trub_chiller_loss', type: 'float' },
+   { name: 'eq_evap_rate', type: 'float' },
+   { name: 'eq_boil_time', type: 'float' },
+   { name: 'eq_calc_boil_volume', type: 'int' },
+   { name: 'eq_top_up_kettle', type: 'float' },
+   { name: 'eq_hop_utilization', type: 'float' },
+   { name: 'eq_notes', type: 'string' },
+   { name: 'eq_lauter_volume', type: 'float' },
+   { name: 'eq_lauter_height', type: 'float' },
+   { name: 'eq_lauter_deadspace', type: 'float' },
+   { name: 'eq_kettle_volume', type: 'float' },
+   { name: 'eq_kettle_height', type: 'float' },
+   { name: 'eq_mash_volume', type: 'float' },
+   { name: 'eq_mash_max', type: 'float' },
+   { name: 'eq_efficiency', type: 'float' },
+   { name: 'brew_date_start', type: 'string' },
+   { name: 'brew_mash_ph', type: 'float' },
+   { name: 'brew_mash_sg', type: 'float' },
+   { name: 'brew_mash_efficiency', type: 'float' },
+   { name: 'brew_sparge_est', type: 'float' },
+   { name: 'brew_sparge_ph', type: 'float' },
+   { name: 'brew_preboil_volume', type: 'float' },
+   { name: 'brew_preboil_sg', type: 'float' },
+   { name: 'brew_preboil_ph', type: 'float' },
+   { name: 'brew_preboil_efficiency', type: 'float' },
+   { name: 'brew_aboil_volume', type: 'float' },
+   { name: 'brew_aboil_sg', type: 'float' },
+   { name: 'brew_aboil_ph', type: 'float' },
+   { name: 'brew_aboil_efficiency', type: 'float' },
+   { name: 'brew_cooling_method', type: 'int' },
+   { name: 'brew_cooling_time', type: 'float' },
+   { name: 'brew_cooling_to', type: 'float' },
+   { name: 'brew_whirlpool9', type: 'float' },
+   { name: 'brew_whirlpool7', type: 'float' },
+   { name: 'brew_whirlpool6', type: 'float' },
+   { name: 'brew_whirlpool2', type: 'float' },
+   { name: 'brew_fermenter_volume', type: 'float' },
+   { name: 'brew_fermenter_extrawater', type: 'float' },
+   { name: 'brew_fermenter_tcloss', type: 'float' },
+   { name: 'brew_aeration_time', type: 'float' },
+   { name: 'brew_aeration_speed', type: 'float' },
+   { name: 'brew_aeration_type', type: 'int' },
+   { name: 'brew_fermenter_sg', type: 'float' },
+   { name: 'brew_fermenter_ibu', type: 'float' },
+   { name: 'brew_fermenter_color', type: 'float' },
+   { name: 'brew_date_end', type: 'string' },
+   { name: 'og', type: 'float' },
+   { name: 'fg', type: 'float' },
+   { name: 'primary_start_temp', type: 'float' },
+   { name: 'primary_max_temp', type: 'float' },
+   { name: 'primary_end_temp', type: 'float' },
+   { name: 'primary_end_sg', type: 'float' },
+   { name: 'primary_end_date', type: 'string' },
+   { name: 'secondary_temp', type: 'float' },
+   { name: 'secondary_end_sg', type: 'float' },
+   { name: 'secondary_end_date', type: 'string' },
+   { name: 'tertiary_temp', type: 'float' },
+   { name: 'package_date', type: 'string' },
+   { name: 'package_volume', type: 'float' },
+   { name: 'package_infuse_amount', type: 'float' },
+   { name: 'package_infuse_abv', type: 'float' },
+   { name: 'package_infuse_notes', type: 'string' },
+   { name: 'package_abv', type: 'float' },
+   { name: 'package_ph', type: 'float' },
+   { name: 'bottle_amount', type: 'float' },
+   { name: 'bottle_carbonation', type: 'float' },
+   { name: 'bottle_priming_water', type: 'float' },
+   { name: 'bottle_priming_amount', type: 'float' },
+   { name: 'bottle_carbonation_temp', type: 'float' },
+   { name: 'keg_amount', type: 'float' },
+   { name: 'keg_carbonation', type: 'float' },
+   { name: 'keg_priming_water', type: 'float' },
+   { name: 'keg_priming_amount', type: 'float' },
+   { name: 'keg_carbonation_temp', type: 'float' },
+   { name: 'keg_forced_carb', type: 'int' },
+   { name: 'keg_pressure', type: 'float' },
+   { name: 'taste_notes', type: 'string' },
+   { name: 'taste_rate', type: 'float' },
+   { name: 'taste_date', type: 'string' },
+   { name: 'taste_color', type: 'string' },
+   { name: 'taste_transparency', type: 'string' },
+   { name: 'taste_head', type: 'string' },
+   { name: 'taste_aroma', type: 'string' },
+   { name: 'taste_taste', type: 'string' },
+   { name: 'taste_mouthfeel', type: 'string' },
+   { name: 'taste_aftertaste', type: 'string' },
+   { name: 'st_name', type: 'string' },
+   { name: 'st_letter', type: 'string' },
+   { name: 'st_guide', type: 'string' },
+   { name: 'st_category', type: 'string' },
+   { name: 'st_category_number', type: 'int' },
+   { name: 'st_type', type: 'int' },
+   { name: 'st_og_min', type: 'float' },
+   { name: 'st_og_max', type: 'float' },
+   { name: 'st_fg_min', type: 'float' },
+   { name: 'st_fg_max', type: 'float' },
+   { name: 'st_ibu_min', type: 'float' },
+   { name: 'st_ibu_max', type: 'float' },
+   { name: 'st_color_min', type: 'float' },
+   { name: 'st_color_max', type: 'float' },
+   { name: 'st_carb_min', type: 'float' },
+   { name: 'st_carb_max', type: 'float' },
+   { name: 'st_abv_min', type: 'float' },
+   { name: 'st_abv_max', type: 'float' },
+   { name: 'type', type: 'int' },
+   { name: 'batch_size', type: 'float' },
+   { name: 'boil_size', type: 'float' },
+   { name: 'boil_time', type: 'float' },
+   { name: 'efficiency', type: 'float' },
+   { name: 'est_og', type: 'float' },
+   { name: 'est_og3', type: 'float' },
+   { name: 'est_fg', type: 'float' },
+   { name: 'est_abv', type: 'float' },
+   { name: 'est_color', type: 'float' },
+   { name: 'color_method', type: 'int' },
+   { name: 'est_ibu', type: 'float' },
+   { name: 'ibu_method', type: 'int' },
+   { name: 'est_carb', type: 'float' },
+   { name: 'sparge_temp', type: 'float' },
+   { name: 'sparge_ph', type: 'float' },
+   { name: 'sparge_volume', type: 'float' },
+   { name: 'sparge_source', type: 'int' },
+   { name: 'sparge_acid_type', type: 'int' },
+   { name: 'sparge_acid_perc', type: 'float' },
+   { name: 'sparge_acid_amount', type: 'float' },
+   { name: 'mash_ph', type: 'float' },
+   { name: 'mash_name', type: 'string' },
+   { name: 'calc_acid', type: 'int' },
+   { name: 'w1_name', type: 'string' },
+   { name: 'w1_amount', type: 'float' },
+   { name: 'w1_calcium', type: 'float' },
+   { name: 'w1_sulfate', type: 'float' },
+   { name: 'w1_chloride', type: 'float' },
+   { name: 'w1_sodium', type: 'float' },
+   { name: 'w1_magnesium', type: 'float' },
+   { name: 'w1_total_alkalinity', type: 'float' },
+   { name: 'w1_ph', type: 'float' },
+   { name: 'w1_cost', type: 'float' },
+   { name: 'w2_name', type: 'string' },
+   { name: 'w2_amount', type: 'float' },
+   { name: 'w2_calcium', type: 'float' },
+   { name: 'w2_sulfate', type: 'float' },
+   { name: 'w2_chloride', type: 'float' },
+   { name: 'w2_sodium', type: 'float' },
+   { name: 'w2_magnesium', type: 'float' },
+   { name: 'w2_total_alkalinity', type: 'float' },
+   { name: 'w2_ph', type: 'float' },
+   { name: 'w2_cost', type: 'float' },
+   { name: 'wg_amount', type: 'float' },
+   { name: 'wg_calcium', type: 'float' },
+   { name: 'wg_sulfate', type: 'float' },
+   { name: 'wg_chloride', type: 'float' },
+   { name: 'wg_sodium', type: 'float' },
+   { name: 'wg_magnesium', type: 'float' },
+   { name: 'wg_total_alkalinity', type: 'float' },
+   { name: 'wg_ph', type: 'float' },
+   { name: 'wb_calcium', type: 'float' },
+   { name: 'wb_sulfate', type: 'float' },
+   { name: 'wb_chloride', type: 'float' },
+   { name: 'wb_sodium', type: 'float' },
+   { name: 'wb_magnesium', type: 'float' },
+   { name: 'wb_total_alkalinity', type: 'float' },
+   { name: 'wb_ph', type: 'float' },
+   { name: 'wa_acid_name', type: 'int' },
+   { name: 'wa_acid_perc', type: 'int' },
+   { name: 'wa_base_name', type: 'int' },
+   { name: 'starter_enable', type: 'int' },
+   { name: 'starter_type', type: 'int' },
+   { name: 'starter_sg', type: 'float' },
+   { name: 'starter_viability', type: 'int' },
+   { name: 'yeast_prod_date', type: 'string' },
+   { name: 'yeast_pitchrate', type: 'float' },
+   { name: 'prop1_type', type: 'int' },
+   { name: 'prop1_volume', type: 'float' },
+   { name: 'prop2_type', type: 'int' },
+   { name: 'prop2_volume', type: 'float' },
+   { name: 'prop3_type', type: 'int' },
+   { name: 'prop3_volume', type: 'float' },
+   { name: 'prop4_type', type: 'int' },
+   { name: 'prop4_volume', type: 'float' },
+   { name: 'divide_type', type: 'int' },
+   { name: 'divide_size', type: 'float' },
+   { name: 'divide_factor', type: 'float' },
+   { name: 'divide_parts', type: 'int' },
+   { name: 'divide_part', type: 'int' },
+   { name: 'fermentables', type: 'string' },
+   { name: 'hops', type: 'string' },
+   { name: 'miscs', type: 'string' },
+   { name: 'yeasts', type: 'string' },
+   { name: 'mashs', type: 'string' }
+  ],
+  id: 'record',
+  url: url + '?record=' + my_record
+ },
+
+ // Load data and select one record.
+ dataAdapter = new $.jqx.dataAdapter(source, {
+  loadComplete: function() {
+   dataRecord = dataAdapter.records[0];
+   // Hidden record uuid
+   $('#name').val(dataRecord.name);
+   $('#code').val(dataRecord.code);
+   $('#birth').val(dataRecord.birth);
+   $('#stage').val(StageData[dataRecord.stage].nl);
+   $('#notes').val(dataRecord.notes);
+   $('#locked').val(dataRecord.locked);
+   $('#eq_name').val(dataRecord.eq_name);
+   $('#eq_notes').val(dataRecord.eq_notes);
+   $('#eq_boil_size').val(dataRecord.eq_boil_size);
+   $('#eq_batch_size').val(dataRecord.eq_batch_size);
+   $('#eq_tun_volume').val(dataRecord.eq_tun_volume);
+   $('#eq_top_up_water').val(dataRecord.eq_top_up_water);
+   $('#eq_trub_chiller_loss').val(dataRecord.eq_trub_chiller_loss);
+   $('#eq_evap_rate').val(dataRecord.eq_evap_rate);
+   $('#eq_boil_time').val(dataRecord.eq_boil_time);
+   $('#eq_top_up_kettle').val(dataRecord.eq_top_up_kettle);
+   $('#eq_hop_utilization').val(dataRecord.eq_hop_utilization);
+   $('#eq_lauter_volume').val(dataRecord.eq_lauter_volume);
+   $('#eq_lauter_deadspace').val(dataRecord.eq_lauter_deadspace);
+   $('#eq_kettle_volume').val(dataRecord.eq_kettle_volume);
+   $('#eq_mash_volume').val(dataRecord.eq_mash_volume);
+   $('#eq_mash_max').val(dataRecord.eq_mash_max);
+   $('#eq_efficiency').val(dataRecord.eq_efficiency);
+   // Brewdate
+   $('#brew_date_start').val(dataRecord.brew_date_start);
+   $('#brew_mash_ph').val(dataRecord.brew_mash_ph);
+   $('#brew_mash_sg').val(dataRecord.brew_mash_sg);
+   $('#brew_mash_efficiency').val(dataRecord.brew_mash_efficiency);
+   // Header Spoelen en filteren
+   $('#brew_sparge_temperature').val(dataRecord.sparge_temp);
+   $('#brew_sparge_volume').val(dataRecord.sparge_volume);
+   $('#brew_sparge_est').val(dataRecord.brew_sparge_est);
+   $('#brew_sparge_ph').val(dataRecord.brew_sparge_ph);
+   // Header Beluchten
+   $('#brew_aeration_type').val(AerationTypeData[dataRecord.brew_aeration_type].nl);
+   $('#brew_aeration_time').val(dataRecord.brew_aeration_time);
+   $('#brew_aeration_speed').val(dataRecord.brew_aeration_speed);
+
+   $('#brew_preboil_ph').val(dataRecord.brew_preboil_ph);
+   $('#brew_preboil_sg').val(dataRecord.brew_preboil_sg);
+   $('#brew_preboil_volume').val(dataRecord.brew_preboil_volume);
+   $('#brew_preboil_efficiency').val(dataRecord.brew_preboil_efficiency);
+   // Header Koelen en whirlpoolen
+   $('#brew_whirlpool9').val(dataRecord.brew_whirlpool9);
+   $('#brew_whirlpool7').val(dataRecord.brew_whirlpool7);
+   $('#brew_whirlpool6').val(dataRecord.brew_whirlpool6);
+   $('#brew_whirlpool2').val(dataRecord.brew_whirlpool2);
+   // Header Naar gistvat
+   $('#brew_fermenter_volume').val(dataRecord.brew_fermenter_volume);
+   $('#brew_fermenter_sg').val(dataRecord.brew_fermenter_sg);
+   $('#brew_fermenter_sg2').val(dataRecord.brew_fermenter_sg);
+   $('#brew_fermenter_ibu').val(dataRecord.brew_fermenter_ibu);
+   $('#brew_fermenter_color').val(dataRecord.brew_fermenter_color);
+   $('#brew_fermenter_extrawater').val(dataRecord.brew_fermenter_extrawater);
+   $('#brew_fermenter_tcloss').val(dataRecord.brew_fermenter_tcloss);
+
+   $('#brew_aboil_ph').val(dataRecord.brew_aboil_ph);
+   $('#brew_aboil_sg').val(dataRecord.brew_aboil_sg);
+   $('#brew_aboil_volume').val(dataRecord.brew_aboil_volume);
+   $('#brew_aboil_efficiency').val(dataRecord.brew_aboil_efficiency);
+   // Header Koelen en whirlpoolen
+   $('#brew_cooling_to').val(dataRecord.brew_cooling_to);
+   $('#brew_cooling_method').val(CoolingTypeData[dataRecord.brew_cooling_method].nl);
+   $('#brew_cooling_time').val(dataRecord.brew_cooling_time);
+   // Niks
+   $('#brew_date_end').val(dataRecord.brew_date_end);
+   $('#og').val(dataRecord.og);
+   $('#fg').val(dataRecord.fg);
+   $('#primary_start_temp').val(dataRecord.primary_start_temp);
+   $('#primary_max_temp').val(dataRecord.primary_max_temp);
+   $('#primary_end_temp').val(dataRecord.primary_end_temp);
+   $('#primary_end_sg').val(dataRecord.primary_end_sg);
+   $('#primary_end_date').val(dataRecord.primary_end_date);
+   $('#secondary_temp').val(dataRecord.secondary_temp);
+   $('#secondary_end_sg').val(dataRecord.secondary_end_sg);
+   $('#secondary_end_date').val(dataRecord.secondary_end_date);
+   $('#tertiary_temp').val(dataRecord.tertiary_temp);
+   $('#package_date').val(dataRecord.package_date);
+   $('#package_volume').val(dataRecord.package_volume);
+   $('#package_infuse_amount').val(dataRecord.package_infuse_amount);
+   $('#package_infuse_abv').val(dataRecord.package_infuse_abv);
+   $('#package_infuse_notes').val(dataRecord.package_infuse_notes);
+   $('#package_abv').val(dataRecord.package_abv);
+   $('#package_ph').val(dataRecord.package_ph);
+   $('#bottle_amount').val(dataRecord.bottle_amount);
+   $('#bottle_carbonation').val(dataRecord.bottle_carbonation);
+   $('#bottle_priming_water').val(dataRecord.bottle_priming_water);
+   $('#bottle_priming_amount').val(dataRecord.bottle_priming_amount);
+   $('#bottle_carbonation_temp').val(dataRecord.bottle_carbonation_temp);
+   $('#keg_amount').val(dataRecord.keg_amount);
+   $('#keg_carbonation').val(dataRecord.keg_carbonation);
+   $('#keg_priming_water').val(dataRecord.keg_priming_water);
+   $('#keg_priming_amount').val(dataRecord.keg_priming_amount);
+   $('#keg_carbonation_temp').val(dataRecord.keg_carbonation_temp);
+   $('#keg_forced_carb').val(dataRecord.keg_forced_carb);
+   $('#keg_pressure').val(dataRecord.keg_pressure);
+   $('#taste_notes').val(dataRecord.taste_notes);
+   $('#taste_rate').val(dataRecord.taste_rate);
+   $('#taste_date').val(dataRecord.taste_date);
+   $('#taste_color').val(dataRecord.taste_color);
+   $('#taste_transparency').val(dataRecord.taste_transparency);
+   $('#taste_head').val(dataRecord.taste_head);
+   $('#taste_aroma').val(dataRecord.taste_aroma);
+   $('#taste_taste').val(dataRecord.taste_taste);
+   $('#taste_mouthfeel').val(dataRecord.taste_mouthfeel);
+   $('#taste_aftertaste').val(dataRecord.taste_aftertaste);
+
+   // Recipe
+   $('#st_name').val(dataRecord.st_name);
+   $('#st_letter').val(dataRecord.st_letter);
+   $('#st_guide').val(dataRecord.st_guide);
+   $('#st_category').val(dataRecord.st_category);
+   $('#st_category_number').val(dataRecord.st_category_number);
+   $('#st_type').val(StyleTypeData[dataRecord.st_type].nl);
+   $('#st_og_min').val(dataRecord.st_og_min);
+   $('#st_og_max').val(dataRecord.st_og_max);
+   $('#st_fg_min').val(dataRecord.st_fg_min);
+   $('#st_fg_max').val(dataRecord.st_fg_max);
+   $('#st_abv_min').val(dataRecord.st_abv_min);
+   $('#st_abv_max').val(dataRecord.st_abv_max);
+   $('#st_color_min').val(dataRecord.st_color_min);
+   $('#st_color_max').val(dataRecord.st_color_max);
+   $('#st_ibu_min').val(dataRecord.st_ibu_min);
+   $('#st_ibu_max').val(dataRecord.st_ibu_max);
+   $('#st_carb_min').val(dataRecord.st_carb_min);
+   $('#st_carb_min2').val(dataRecord.st_carb_min);
+   $('#st_carb_max').val(dataRecord.st_carb_max);
+   $('#st_carb_max2').val(dataRecord.st_carb_max);
+   $('#type').val(RecipeTypeData[dataRecord.type].nl);
+   $('#batch_size').val(dataRecord.batch_size);
+   $('#est_a_vol').val(dataRecord.batch_size * 1.04);
+   $('#boil_size').val(dataRecord.boil_size);
+   $('#est_pre_vol').val(dataRecord.boil_size * 1.04);
+   $('#boil_time').val(dataRecord.boil_time);
+   $('#efficiency').val(dataRecord.efficiency);
+   $('#est_og').val(dataRecord.est_og);
+   $('#est_og2').val(dataRecord.est_og);
+   $('#est_og3').val(dataRecord.est_og3);
+   $('#est_fg').val(dataRecord.est_fg);
+   $('#est_fg2').val(dataRecord.est_fg);
+   $('#est_fg3').val(dataRecord.est_fg);
+   $('#est_color').val(dataRecord.est_color);
+   $('#est_color2').val(dataRecord.est_color);
+   $('#est_abv').val(dataRecord.est_abv);
+   $('#color_method').val(ColorMethodData[dataRecord.color_method].nl);
+   $('#est_ibu').val(dataRecord.est_ibu);
+   $('#est_ibu2').val(dataRecord.est_ibu);
+   $('#ibu_method').val(IBUmethodData[dataRecord.ibu_method].nl);
+   $('#est_carb').val(dataRecord.est_carb);
+   $('#mash_name').val(dataRecord.mash_name);
+   $('#mash_ph').val(dataRecord.mash_ph);
+   $('#sparge_temp').val(dataRecord.sparge_temp);
+   $('#sparge_ph').val(dataRecord.sparge_ph);
+   $('#sparge_volume').val(dataRecord.sparge_volume);
+   $('#sparge_source').val(dataRecord.sparge_source);
+   $('#sparge_acid_type').val(AcidTypeData[dataRecord.sparge_acid_type].nl);
+   $('#sparge_acid_perc').val(dataRecord.sparge_acid_perc);
+   $('#sparge_acid_amount').val(dataRecord.sparge_acid_amount * 1000);
+   $('#calc_acid').val(dataRecord.calc_acid);
+   $('#w1_name').val(dataRecord.w1_name);
+   $('#w1_amount').val(dataRecord.w1_amount);
+   $('#w1_calcium').val(dataRecord.w1_calcium);
+   $('#w1_sulfate').val(dataRecord.w1_sulfate);
+   $('#w1_chloride').val(dataRecord.w1_chloride);
+   $('#w1_sodium').val(dataRecord.w1_sodium);
+   $('#w1_magnesium').val(dataRecord.w1_magnesium);
+   $('#w1_total_alkalinity').val(dataRecord.w1_total_alkalinity);
+   $('#w1_bicarbonate').val(dataRecord.w1_total_alkalinity * 1.22);
+   $('#w1_ph').val(dataRecord.w1_ph);
+   $('#w1_cost').val(dataRecord.w1_cost);
+   $('#w2_name').val(dataRecord.w2_name);
+   $('#w2_amount').val(dataRecord.w2_amount);
+   $('#w2_calcium').val(dataRecord.w2_calcium);
+   $('#w2_sulfate').val(dataRecord.w2_sulfate);
+   $('#w2_chloride').val(dataRecord.w2_chloride);
+   $('#w2_sodium').val(dataRecord.w2_sodium);
+   $('#w2_magnesium').val(dataRecord.w2_magnesium);
+   $('#w2_total_alkalinity').val(dataRecord.w2_total_alkalinity);
+   $('#w2_bicarbonate').val(dataRecord.w2_total_alkalinity * 1.22);
+   $('#w2_ph').val(dataRecord.w2_ph);
+   $('#w2_cost').val(dataRecord.w2_cost);
+   $('#wg_amount').val(dataRecord.wg_amount);
+   $('#wg_calcium').val(dataRecord.wg_calcium);
+   $('#wg_sulfate').val(dataRecord.wg_sulfate);
+   $('#wg_chloride').val(dataRecord.wg_chloride);
+   $('#wg_sodium').val(dataRecord.wg_sodium);
+   $('#wg_magnesium').val(dataRecord.wg_magnesium);
+   $('#wg_total_alkalinity').val(dataRecord.wg_total_alkalinity);
+   $('#wg_ph').val(dataRecord.wg_ph);
+   $('#wb_calcium').val(dataRecord.wb_calcium);
+   $('#wb_sulfate').val(dataRecord.wb_sulfate);
+   $('#wb_chloride').val(dataRecord.wb_chloride);
+   $('#wb_sodium').val(dataRecord.wb_sodium);
+   $('#wb_magnesium').val(dataRecord.wb_magnesium);
+   $('#wb_total_alkalinity').val(dataRecord.wb_total_alkalinity);
+   $('#wb_ph').val(dataRecord.wb_ph);
+   $('#wa_acid_name').val(dataRecord.wa_acid_name);
+   $('#wa_acid_perc').val(dataRecord.wa_acid_perc);
+   $('#starter_type').val(StarterTypeData[dataRecord.starter_type].nl);
+   $('#starter_sg').val(dataRecord.starter_sg);
+   $('#starter_viability').val(dataRecord.starter_viability);
+   $('#yeast_prod_date').val(dataRecord.yeast_prod_date);
+   $('#yeast_pitchrate').val(dataRecord.yeast_pitchrate);
+   $('#prop1_type').val(StarterTypeData[dataRecord.prop1_type].nl);
+   $('#prop1_volume').val(dataRecord.prop1_volume);
+   $('#prop2_type').val(StarterTypeData[dataRecord.prop2_type].nl);
+   $('#prop2_volume').val(dataRecord.prop2_volume);
+   $('#prop3_type').val(StarterTypeData[dataRecord.prop3_type].nl);
+   $('#prop3_volume').val(dataRecord.prop3_volume);
+   $('#prop4_type').val(StarterTypeData[dataRecord.prop4_type].nl);
+   $('#prop4_volume').val(dataRecord.prop4_volume);
+   $('#divide_type').val(SplitData[dataRecord.divide_type].nl);
+   if (dataRecord.divide_type > 0)
+    $('#divide_batch').val((dataRecord.divide_part + 1) + ' van ' + (dataRecord.divide_parts + 1));
+   else
+    $('#divide_batch').val('n.v.t.');
+   // hidden divide_size
+   // hidden divide_factor
+   // hidden divide_parts
+   // hidden divide_part
+   editFermentable(dataRecord);
+   editHop(dataRecord);
+   editMisc(dataRecord);
+   editYeast(dataRecord);
+   editMash(dataRecord);
+   calcStage();
+   $('#jqxTabs').jqxTabs('select', 2);
+   data_loaded = 1;
+  },
+  loadError: function(jqXHR, status, error) {
+   console.log('main data load error: ' + status + ' ' + error);
+  }
+ });
+
+ // Inline fermentables editor
+ var editFermentable = function(data) {
+  var fermentableSource = {
+   localdata: data.fermentables,
+   datafields: [
+    { name: 'f_name', type: 'string' },
+    { name: 'f_origin', type: 'string' },
+    { name: 'f_supplier', type: 'string' },
+    { name: 'f_amount', type: 'float' },
+    { name: 'f_cost', type: 'float' },
+    { name: 'f_type', type: 'int' },
+    { name: 'f_yield', type: 'float' },
+    { name: 'f_color', type: 'float' },
+    { name: 'f_coarse_fine_diff', type: 'float' },
+    { name: 'f_moisture', type: 'float' },
+    { name: 'f_diastatic_power', type: 'float' },
+    { name: 'f_protein', type: 'float' },
+    { name: 'f_max_in_batch', type: 'float' },
+    { name: 'f_graintype', type: 'int' },
+    { name: 'f_added', type: 'int' },
+    { name: 'f_dissolved_protein', type: 'float' },
+    { name: 'f_recommend_mash', type: 'int' },
+    { name: 'f_add_after_boil', type: 'int' },
+    { name: 'f_adjust_to_total_100', type: 'int' },
+    { name: 'f_percentage', type: 'float' },
+    { name: 'f_di_ph', type: 'float' },
+    { name: 'f_acid_to_ph_57', type: 'float' },
+    { name: 'f_inventory', type: 'float' },
+    { name: 'f_avail', type: 'int' }
+   ],
+  },
+  fermentableAdapter = new $.jqx.dataAdapter(fermentableSource);
+
+  $('#fermentableGrid').jqxGrid({
+   width: 1240,
+   height: 470,
+   source: fermentableAdapter,
+   theme: theme,
+   editable: false,
+   ready: function() { calcFermentables(); $('#jqxTabs').jqxTabs('next'); },
+   columns: [
+    { text: 'Vergistbaar ingredi&euml;nt', datafield: 'f_name' },
+    { text: 'Leverancier', datafield: 'f_supplier', width: 180 },
+    { text: 'Kleur', datafield: 'f_color', width: 90, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value, 'f0') + ' EBC</span>';
+     }
+    },
+    { text: 'Type', width: 100, datafield: 'f_type',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + FermentableTypeData[value].nl + '</span>';
+     }
+    },
+    { text: 'Moment', width: 110, datafield: 'f_added',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + AddedData[value].nl + '</span>';
+     }
+    },
+    { text: 'Maxinbatch', datafield: 'f_max_in_batch', hidden: true },
+    { text: 'Opbrengst', datafield: 'f_yield', width: 90, align: 'right', cellsalign: 'right', cellsformat: 'p1' },
+    { text: 'Gewicht Kg', datafield: 'f_amount', width: 110, align: 'right', cellsalign: 'right', cellsformat: 'f3' },
+    { text: 'Voorraad Kg', datafield: 'f_inventory', width: 110, align: 'right',
+     cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
+      var color = (value < rowdata.f_amount) ? '#ff4040':'#ffffff';
+      if (block_fermentable(dataRecord.inventory_reduced, rowdata.f_added) == false) {
+       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + fermentableAdapter.formatNumber(value, 'f3') + '</span>';
+      } else {
+       return '<span></span>';
+      }
+     }
+    },
+    { text: 'Procent', datafield: 'f_percentage', width: 90, align: 'right',
+     cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
+      if (rowdata.f_added >= 4)
+       return '<span></span>';
+      var color = (value > rowdata.f_max_in_batch) ? '#ff4040':'#ffffff';
+      return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + fermentableAdapter.formatNumber(value, 'p1') + '</span>';
+     }
+    },
+    { text: '100%', datafield: 'f_adjust_to_total_100', width: 70, align: 'center', cellsalign: 'center',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      if (value == 0)
+       return '<span></span>';
+      return '<span><img style="float:left; margin-left:25px; margin-top:4px;" src="images/dialog-ok-apply.png"></span>';
+     }
+    }
+   ]
+  });
+ };
+
+ // Inline hops editor
+ var editHop = function(data) {
+  var hopSource = {
+   localdata: data.hops,
+   datafields: [
+    { name: 'h_name', type: 'string' },
+    { name: 'h_origin', type: 'string' },
+    { name: 'h_amount', type: 'float' },
+    { name: 'h_cost', type: 'float' },
+    { name: 'h_type', type: 'int' },
+    { name: 'h_form', type: 'int' },
+    { name: 'h_useat', type: 'int' },
+    { name: 'h_time', type: 'int' },
+    { name: 'h_alpha', type: 'float' },
+    { name: 'h_beta', type: 'float' },
+    { name: 'h_hsi', type: 'float' },
+    { name: 'h_humulene', type: 'float' },
+    { name: 'h_caryophyllene', type: 'float' },
+    { name: 'h_cohumulone', type: 'float' },
+    { name: 'h_myrcene', type: 'float' },
+    { name: 'h_total_oil', type: 'float' },
+    { name: 'h_inventory', type: 'float' },
+    { name: 'h_avail', type: 'int' },
+    { name: 'h_utilisation', type: 'float' },
+    { name: 'h_bu_factor', type: 'float' }
+   ],
+  },
+  hopAdapter = new $.jqx.dataAdapter(hopSource);
+
+  $('#hopGrid').jqxGrid({
+   width: 1240,
+   height: 560,
+   source: hopAdapter,
+   theme: theme,
+   editable: false,
+   ready: function() { $('#jqxTabs').jqxTabs('next'); },
+   columns: [
+    { text: 'Hop', datafield: 'h_name' },
+    { text: 'Origin', width: 180, datafield: 'h_origin' },
+    { text: 'Type', width: 90, datafield: 'h_type',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopTypeData[value].nl + '</span>';
+     }
+    },
+    { text: 'Vorm', width: 110, datafield: 'h_form',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopFormData[value].nl + '</span>';
+     }
+    },
+    { text: 'Alpha', datafield: 'h_alpha', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'p1' },
+    { text: 'Gebruik', width: 110, datafield: 'h_useat',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + HopUseData[value].nl + '</span>';
+     }
+    },
+    { text: 'Tijdsduur', datafield: 'h_time', width: 90, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var duration = '';
+      if ((rowdata.h_useat == 2) || (rowdata.h_useat == 4))   // Boil, Whirlpool
+       duration = dataAdapter.formatNumber(value, 'f0') + ' min.';
+      else if (rowdata.h_useat == 5)       // Dry hop
+       duration = dataAdapter.formatNumber(value / 1440, 'f0') + ' dagen';
+      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>';
+     }
+    },
+    { text: 'IBU', datafield: 'ibu', width: 80, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var ibu = toIBU(rowdata.h_useat, rowdata.h_form, preboil_sg, parseFloat(dataRecord.batch_size),
+                parseFloat(rowdata.h_amount), parseFloat(rowdata.h_time), parseFloat(rowdata.h_alpha), dataRecord.ibu_method,
+                dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6);
+      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(ibu, 'f1') + '</span>';
+     }
+    },
+    { text: 'Gewicht', datafield: 'h_amount', width: 110, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var amount = dataAdapter.formatNumber(value, 'f1') + ' kg';
+      if (value < 1)
+       amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
+      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>';
+     }
+    },
+    { text: 'Voorraad', datafield: 'h_inventory', width: 110, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      if (block_hop(dataRecord.inventory_reduced, rowdata.h_useat) == false) {
+       var amount = dataAdapter.formatNumber(value, 'f1') + ' kg',
+       color = (value < rowdata.h_amount) ? '#ff4040':'#ffffff';
+       if (value < 1)
+        amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
+       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
+      } else {
+       return '<span></span>';
+      }
+     }
+    }
+   ]
+  });
+ };
+
+ // Inline miscs editor
+ var editMisc = function(data) {
+  var miscSource = {
+   localdata: data.miscs,
+   datafields: [
+    { name: 'm_name', type: 'string' },
+    { name: 'm_amount', type: 'float' },
+    { name: 'm_cost', type: 'float' },
+    { name: 'm_type', type: 'int' },
+    { name: 'm_use_use', type: 'int' },
+    { name: 'm_time', type: 'float' },
+    { name: 'm_amount_is_weight', type: 'int' },
+    { name: 'm_inventory', type: 'float' },
+    { name: 'm_avail', type: 'int' }
+   ],
+  },
+  miscAdapter = new $.jqx.dataAdapter(miscSource, {
+   beforeLoadComplete: function(records) {
+    var row, i, data = new Array();
+    for (i = 0; i < records.length; i++) {
+     row = records[i];
+     data.push(row);
+     // Initial set water agent values.
+     if (row.m_use_use == 1) {  // Mash
+      switch (row.m_name) {
+       case 'CaCl2':
+        $('#wa_cacl2').val(row.m_amount * 1000);
+        break;
+       case 'CaSO4':
+        $('#wa_caso4').val(row.m_amount * 1000);
+        break;
+       case 'MgSO4':
+        $('#wa_mgso4').val(row.m_amount * 1000);
+        break;
+       case 'NaCl':
+        $('#wa_nacl').val(row.m_amount * 1000);
+        break;
+       case 'MgCl2':
+        $('#wa_mgcl2').val(row.m_amount * 1000);
+        break;
+       case 'NaHCO3':
+        $('#wa_nahco3').val(row.m_amount * 1000);
+        break;
+       case 'CaCO3':
+        $('#wa_caco3').val(row.m_amount * 1000);
+        break;
+       case 'Melkzuur':
+        $('#wa_acid_name').val(AcidTypeData[0].nl);
+        $('#wa_acid').val(row.m_amount * 1000);
+        $('#wa_acid_perc').val(AcidTypeData[0].AcidPrc);
+        last_acid = 'Melkzuur';
+        break;
+       case 'Zoutzuur':
+        $('#wa_acid_name').val(AcidTypeData[1].nl);
+        $('#wa_acid').val(row.m_amount * 1000);
+        $('#wa_acid_perc').val(AcidTypeData[1].AcidPrc);
+        last_acid = 'Zoutzuur';
+        break;
+       case 'Fosforzuur':
+        $('#wa_acid_name').val(AcidTypeData[2].nl);
+        $('#wa_acid').val(row.m_amount * 1000);
+        $('#wa_acid_perc').val(AcidTypeData[2].AcidPrc);
+        last_acid = 'Fosforzuur';
+        break;
+       case 'Zwavelzuur':
+        $('#wa_acid_name').val(AcidTypeData[3].nl);
+        $('#wa_acid').val(row.m_amount * 1000);
+        $('#wa_acid_perc').val(AcidTypeData[3].AcidPrc);
+        last_acid = 'Zwavelzuur';
+        break;
+      }
+     }
+     if (row.m_use_use == 6) {  // Sparge
+      switch (row.m_name) {
+       case 'CaCl2':
+        $('#ss_cacl2').val(row.m_amount * 1000);
+        break;
+       case 'CaSO4':
+        $('#ss_caso4').val(row.m_amount * 1000);
+        break;
+       case 'MgSO4':
+        $('#ss_mgso4').val(row.m_amount * 1000);
+        break;
+       case 'NaCl':
+        $('#ss_nacl').val(row.m_amount * 1000);
+        break;
+       case 'MgCl2':
+        $('#ss_mgcl2').val(row.m_amount * 1000);
+        break;
+      }
+     }
+    }
+    return data;
+   },
+   loadError: function(jqXHR, status, error) { console.log('miscs load error ' + status + ' ' + error); },
+  });
+  $('#miscGrid').jqxGrid({
+   width: 1240,
+   height: 575,
+   source: miscAdapter,
+   theme: theme,
+   editable: false,
+   ready: function() { $('#jqxTabs').jqxTabs('next'); },
+   columns: [
+    { text: 'Ingredient', datafield: 'm_name' },
+    { text: 'Type', width: 140, datafield: 'm_type',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + MiscTypeData[value].nl + '</span>';
+     }
+    },
+    { text: 'Gebruik', width: 140, datafield: 'm_use_use',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 3px; margin-top: 6px; float: left;">' + MiscUseData[value].nl + '</span>';
+     }
+    },
+    { text: 'Tijd', datafield: 'm_time', width: 90, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var duration = '';
+      if (rowdata.m_use_use == 2) // Boil
+       duration = dataAdapter.formatNumber(value, 'f0') + ' min.';
+      else if ((rowdata.m_use_use == 3) || (rowdata.m_use_use == 4)) // Primary or Secondary
+       duration = dataAdapter.formatNumber(value / 1440, 'f0') + ' dagen';
+      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + duration + '</span>';
+     }
+    },
+    { text: 'Hoeveel', datafield: 'm_amount', width: 110, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var vstr = rowdata.m_amount_is_weight ? 'gr' : 'ml';
+      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value * 1000, 'f2') + ' ' + vstr + '</span>';
+     }
+    },
+    { text: 'Voorraad', datafield: 'm_inventory', width: 110, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      if (block_misc(dataRecord.inventory_reduced, rowdata.m_use_use) == false) {
+       var vstr = rowdata.m_amount_is_weight ? 'gr' : 'ml',
+       color = (value < rowdata.m_amount) ? '#ff4040':'#ffffff',
+       amount = dataAdapter.formatNumber(value * 1000, 'f2') + ' ' + vstr;
+       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
+      } else {
+       return '<span></span>';
+      }
+     }
+    }
+   ]
+  });
+ };
+
+ // Inline yeasts editor
+ var editYeast = function(data) {
+  var yeastSource = {
+   localdata: data.yeasts,
+   datafields: [
+    { name: 'y_name', type: 'string' },
+    { name: 'y_laboratory', type: 'string' },
+    { name: 'y_product_id', type: 'string' },
+    { name: 'y_amount', type: 'float' },
+    { name: 'y_cost', type: 'float' },
+    { name: 'y_type', type: 'int' },
+    { name: 'y_form', type: 'int' },
+    { name: 'y_flocculation', type: 'int' },
+    { name: 'y_min_temperature', type: 'float' },
+    { name: 'y_max_temperature', type: 'float' },
+    { name: 'y_attenuation', type: 'float' },
+    { name: 'y_use', type: 'int' },
+    { name: 'y_cells', type: 'float' },
+    { name: 'y_tolerance', type: 'float' },
+    { name: 'y_inventory', type: 'float' },
+    { name: 'y_sta1', type: 'int' },
+    { name: 'y_bacteria', type: 'int' },
+    { name: 'y_harvest_top', type: 'int' },
+    { name: 'y_harvest_time', type: 'int' },
+    { name: 'y_pitch_temperature', type: 'float' },
+    { name: 'y_pofpos', type: 'int' },
+    { name: 'y_zymocide', type: 'int' },
+    { name: 'y_gr_hl_lo', type: 'int' },
+    { name: 'y_sg_lo', type: 'float' },
+    { name: 'y_gr_hl_hi', type: 'int' },
+    { name: 'y_sg_hi', type: 'float' },
+    { name: 'y_avail', type: 'int' }
+   ],
+  },
+  yeastAdapter = new $.jqx.dataAdapter(yeastSource);
+
+  $('#yeastGrid').jqxGrid({
+   width: 1240,
+   height: 325,
+   source: yeastAdapter,
+   theme: theme,
+   editable: false,
+   ready: function() { $('#jqxTabs').jqxTabs('next'); },
+   columns: [
+    { text: 'Gist', datafield: 'y_name' },
+    { text: 'Laboratorium', width: 150, datafield: 'y_laboratory' },
+    { text: 'Code', width: 90, datafield: 'y_product_id' },
+    { text: 'Soort', width: 100, datafield: 'y_form',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastFormData[value].nl + '</span>';
+     }
+    },
+    { text: 'Min. &deg;C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_min_temperature' },
+    { text: 'Max. &deg;C', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_max_temperature' },
+    { text: 'Tol. %', width: 60, align: 'right', cellsalign: 'right', datafield: 'y_tolerance',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var amount = '', color = (dataRecord.est_abv > value) ? '#ff4040':'#ffffff';
+      if (value > 0) {
+       amount = dataAdapter.formatNumber(value, 'f1');
+      }
+      return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
+     }
+    },
+    { text: 'Attn. %', width: 70, align: 'right', cellsalign: 'right', datafield: 'y_attenuation', cellsformat: 'f1' },
+    { text: 'Voor', width: 120, datafield: 'y_use',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      return '<span style="margin: 4px; margin-top: 6px; float: left;">' + YeastUseData[value].nl + '</span>';
+     }
+    },
+    { text: 'Hoeveel', datafield: 'y_amount', width: 90, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var amount = dataAdapter.formatNumber(value * 1000, 'f0') + ' ml';
+      if (rowdata.y_form == 0) // Liquid
+       amount = dataAdapter.formatNumber(value, 'f0') + ' pk';
+      else if (rowdata.y_form == 1 || rowdata.y_form == 6) // Dry
+       amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
+      return '<span style="margin: 4px; margin-top: 6px; float: right;">' + amount + '</span>';
+     }
+    },
+    { text: 'Voorraad', datafield: 'y_inventory', width: 90, align: 'right',
+     cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+      var color, amount;
+      if (block_yeast(dataRecord.inventory_reduced, rowdata.y_use) == false) {
+       color = '#ffffff';
+       if (value < rowdata.y_amount)
+        color = '#ff4040';
+       amount = dataAdapter.formatNumber(value * 1000, 'f0') + ' ml';
+       if (rowdata.y_form == 0)        // Liquid
+        amount = dataAdapter.formatNumber(value, 'f0') + ' pk';
+       else if (rowdata.y_form == 1 || rowdata.y_form == 6)   // Dry
+        amount = dataAdapter.formatNumber(value * 1000, 'f1') + ' gr';
+       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + amount + '</span>';
+      } else {
+       return '<span></span>';
+      }
+     }
+    }
+   ]
+  });
+ };
+
+ // inline mash editor
+ var editMash = function(data) {
+  var mashSource = {
+   localdata: data.mashs,
+   datafields: [
+    { name: 'step_name', type: 'string' },
+    { name: 'step_type', type: 'int' },
+    { name: 'step_volume', type: 'float' },
+    { name: 'step_infuse_amount', type: 'float' },
+    { name: 'step_infuse_temp', type: 'float' },
+    { name: 'step_temp', type: 'float' },
+    { name: 'step_time', type: 'float' },
+    { name: 'step_wg_ratio', type: 'float' },
+    { name: 'ramp_time', type: 'float' },
+    { name: 'end_temp', type: 'float' },
+    { name: 'step_ph', type: 'float' },
+    { name: 'step_sg', type: 'float' }
+   ],
+  },
+  mashAdapter = new $.jqx.dataAdapter(mashSource);
+
+  $('#mashGrid').jqxGrid({
+   width: 1240,
+   height: 400,
+   source: mashAdapter,
+   theme: theme,
+   selectionmode: 'singlerow',
+   editable: false,
+   ready: function() {
+    /* Calculate the whole recipe */
+    console.log('ready mashs, start calculations');
+    /* calcFermentables() must be first and is done by the grid load. Here it is too late. */
+    calcMash();
+    calcWater();
+    calcIBUs();
+    whirlpoolHops();
+    calcMiscs();
+    calcViability();
+    calcYeast();
+    kookTijd();
+    calcFermentation();
+    calcCarbonation();
+    $('#FLog').jqxButton({ disabled: (dataRecord.log_fermentation) ? false : true});
+    $('#ILog').jqxButton({ disabled: (dataRecord.log_ispindel) ? false : true});
+    $('#CLog').jqxButton({ disabled: (dataRecord.log_co2pressure) ? false : true});
+    console.log('calculations ready');
+    $('#jqxLoader').jqxLoader('close');
+    $('#jqxTabs').jqxTabs('first');
+   },
+   columns: [
+    { text: 'Stap naam', datafield: 'step_name' },
+    { text: 'Stap type', datafield: 'step_type', width: 150,
+      cellsrenderer: function(index, datafield, value, defaultvalue, column, rowdata) {
+       return '<span style="margin: 4px; margin-top: 6px; float: left;">' + MashStepTypeData[value].nl + '</span>';
+      }
+    },
+    { text: 'Start &deg;C', datafield: 'step_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' },
+    { text: 'Eind &deg;C', datafield: 'end_temp', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f1' },
+    { text: 'Rust min.', datafield: 'step_time', width: 80, align: 'right', cellsalign: 'right' },
+    { text: 'Stap min.', datafield: 'ramp_time', width: 80, align: 'right', cellsalign: 'right' },
+    { text: 'Inf/dec L.', datafield: 'step_infuse_amount', width: 80, align: 'right',
+      cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
+       if (rowdata.step_type == 1)
+        return '<span></span>';
+       var color = '#ffffff';
+       var mvol = mashkg * MaltVolume;
+       if ((rowdata.step_wg_ratio * mashkg + mvol) > dataRecord.eq_tun_volume)
+        color = '#ff4040';
+       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + dataAdapter.formatNumber(value, 'f1') + '</span>';
+      }
+    },
+    { text: 'Inf/dec &deg;C', datafield: 'step_infuse_temp', width: 90, align: 'right',
+      cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
+       if (rowdata.step_type == 1)
+        return '<span></span>';
+       return '<span style="margin: 4px; margin-top: 6px; float: right;">' + dataAdapter.formatNumber(value, 'f2') + '</span>';
+      }
+    },
+    { text: 'L/Kg.', datafield: 'step_wg_ratio', width: 80, align: 'right',
+      cellsrenderer: function(row, columnfield, value, defaulthtml, columnproperties, rowdata) {
+       var color = '#ffffff';
+       if (value < 2.0 || value > 6.0)
+        color = '#ff4040';
+       return '<span style="margin: 4px; margin-top: 6px; float: right; color: ' + color + ';">' + dataAdapter.formatNumber(value, 'f2') + '</span>';
+      }
+    },
+    { text: 'pH', datafield: 'step_ph', width: 70, align: 'right', cellsalign: 'right', cellsformat: 'f2' },
+    { text: 'SG', datafield: 'step_sg', width: 80, align: 'right', cellsalign: 'right', cellsformat: 'f3' }
+   ]
+  });
+ };
+
+ /*
+  * Remove the top menu so that we MUST use the button to leave the editor.
+  */
+ $('#jqxMenu').jqxMenu('destroy');
+ console.log('record:' + my_record + '  return:' + my_return + '  theme:' + theme);
+ $('#jqxLoader').jqxLoader({ width: 250, height: 150, isModal: true, text: 'Laden product ...', theme: theme });
+ $('#jqxLoader').jqxLoader('open');
+
+ /* Moved to before all functions */
+ dataAdapter.dataBind();
+
+ /*
+  * Generic functions
+  */
+ function kookTijd() {
+  if (dataRecord.boil_time) {
+   $('#brew_pmpt_koken').html('Koken ' + dataRecord.boil_time + ' minuten');
+  } else {
+   $('#brew_pmpt_koken').html('Koken "no-boil"');
+  }
+ }
+
+ function infusionVol(step_infused, step_mashkg, infuse_temp, step_temp, last_temp) {
+  var a = last_temp * (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + step_infused * SpecificHeatWater + step_mashkg * SpecificHeatMalt);
+  var b = step_temp * (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + step_infused * SpecificHeatWater + step_mashkg * SpecificHeatMalt);
+  var vol = Round(((b - a) / ((infuse_temp - step_temp) * SpecificHeatWater)), 2);
+  return vol;
+ }
+
+ function decoctionVol(step_volume, step_temp, prev_temp) {
+  var a = (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + step_volume * SpecificHeatWater) * (step_temp - prev_temp);
+  var b = SpecificHeatWater * (99 - step_temp);
+  var vol = 0;
+  if (b > 0)
+   vol = Round(a / b, 6);
+  return vol;
+ }
+
+ function calcViability() {
+  var vpm = 1.00;
+  var max = 100;
+  var rowscount = dataRecord.yeasts.length;
+  if (rowscount) {
+   for (i = 0; i < rowscount; i++) {
+    row = dataRecord.yeasts[i];
+    if (row.y_use == 0) {
+     if (row.y_form == 0) { // Liquid
+      vpm = 0.80;
+      max = 97;
+      if (row.y_laboratory == 'White Labs') { // PurePitch
+       vpm = 0.95;
+       max = 100;
+      }
+     } else if (row.y_form == 1) { // dry yeast
+      vpm = 0.998;
+      max = 100;
+     } else if (row.y_form == 6) { // Dried kveik
+      vpm = 0.92;
+      max = 100;
+     } else { // Slant, Culture, Frozen, Bottle
+      vpm = 0.99;
+      max = 97;
+     }
+    }
+   }
+  }
+  var base = max;
+  var days = 0;
+
+  if (parseFloat($('#yeast_prod_date').val()) > 2000) {
+   console.log('calculate viability');
+   var d = new Date();
+   var date2 = $('#yeast_prod_date').val();
+   date2 = date2.split('-');
+   // Now we convert the array to a Date object
+   var date1 = new Date(d.getFullYear(), d.getMonth(), d.getDate());
+   date2 = new Date(date2[0], date2[1] - 1, date2[2]);
+   var diff = parseInt(date1.getTime()) - parseInt(date2.getTime());
+   days = Math.floor(diff/1000/60/60/24);
+
+   var degrade = 1 - ((1 - vpm) / 30.41);  // viability degradation per day.
+   for (i = 0; i < days; i++) {
+    base = base * degrade;
+   }
+   if (base > max) {
+    base = max;
+   }
+   base = Math.round(base);
+  }
+  console.log('age:' + days + ' max:' + max + ' vpm:' + vpm + ' base:' + base);
+
+  if (dataRecord.starter_viability != base) {
+   dataRecord.starter_viability = base;
+   $('#starter_viability').val(dataRecord.starter_viability);
+  }
+ }
+
+ function calcSupplies() {
+  if (dataRecord.inventory_reduced > 6) {
+   $('#ok_pmpt').hide();
+   return;
+  }
+  if (ok_fermentables && ok_hops && ok_miscs && ok_yeasts && ok_waters)
+   $('#ok_supplies').html("<img src='images/dialog-ok-apply.png'>");
+  else
+   $('#ok_supplies').html("<img src='images/dialog-error.png'>");
+ }
+
+ /*
+  * All calculations that depend on changes in the fermentables,
+  * volumes and equipments.
+  */
+ function calcFermentables() {
+
+  var sugarsf = 0,  // fermentable sugars mash + boil
+  sugarsm = 0,      // fermentable sugars in mash
+  vol = 0,          // Volume sugars after boil
+  addedS = 0,       // Added sugars after boil
+  addedmass = 0,    // Added mass after boil
+  mvol = 0,         // mash volume
+  infuse = 0,	    // mash infuse volume
+  colort = 0,       // Colors srm * vol totals
+  colorh = 0,       // Colors ebc * vol * kt
+  colorn = 0,       // Colors ebc * pt * pct
+  my_100 = false,
+  mashtime = 0,     // Total mash time
+  mashtemp = 0,     // Average mash temperature
+  bv = 0.925,       // Bierverlies rendement
+  sr = 0.95,        // Mash en spoel rendement
+  lintner = 0,      // Total recipe lintner
+  i, row, rows, org, timem, aboil_volume, spoelw, ogx, topw, s = 0, d, v, x,
+  sug, alc, pt, cw, color, scolor, fig;
+
+  /* Init global variables */
+  psugar = 0;
+  pcara = 0;
+  mashkg = 0;
+  ok_fermentables = 1;    // All is in stock.
+  ok_yeasts = 1;
+
+  if (dataRecord.mashs.length) {
+   for (i = 0; i < dataRecord.mashs.length; i++) {
+    row = dataRecord.mashs[i];
+    if (parseFloat(row.step_type) == 0) // Infusion
+     mvol += parseFloat(row.step_infuse_amount);
+    if (row.step_temp <= 75 && row.step_temp >= 60) { // Ignore mashout
+     timem = row.step_time;
+     if (i > 0)
+      timem += row.ramp_time;
+     mashtime += timem;
+     mashtemp += timem * row.step_temp;
+    }
+   }
+   infuse = mvol;
+   mashtemp = Round(mashtemp / mashtime, 2);
+  } else {
+   console.log("calcFermentables() no mash steps");
+  }
+
+  if (! dataRecord.fermentables.length) {
+   console.log("calcFermentables() no fermentables");
+   return; // grid not yet loaded.
+  }
+
+  for (i = 0; i < dataRecord.fermentables.length; i++) {
+   row = dataRecord.fermentables[i];
+   if (row.f_adjust_to_total_100)
+    my_100 = true;
+   if (row.f_type == 1 && row.f_added < 4) // Sugar
+    psugar += row.f_percentage;
+   if (row.f_graintype == 2 && row.f_added < 4)    // Crystal
+    pcara += row.f_percentage;
+   d = row.f_amount * (row.f_yield / 100) * (1 - row.f_moisture / 100);
+   if (row.f_added == 0) { // Mash
+    if (mvol > 0) { // Only if mash already known.
+     mvol += row.f_amount * row.f_moisture / 100;
+     s += d;
+    }
+    d = parseFloat(dataRecord.efficiency) / 100 * d;
+    sugarsm += d;
+    mashkg += parseFloat(row.f_amount);
+   }
+   if (row.f_added == 0 || row.f_added == 1)       // Mash or Boil
+    sugarsf += d;
+   if (row.f_added == 2 || row.f_added == 3) {     // Fermentation or lagering
+    x = (row.f_yield / 100) * (1 - row.f_moisture / 100);
+    addedS += row.f_amount * x;
+    addedmass += row.f_amount;
+    vol += (x * sugardensity + (1 - x) * 1) * row.f_amount;
+   }
+   if (row.f_added < 4) {
+    colort += row.f_amount * ebc_to_srm(row.f_color);
+    colorh += row.f_amount * row.f_color * get_kt(row.f_color);
+    colorn += (row.f_percentage / 100) * row.f_color;       // For 8.6 Pt wort.
+   }
+   if (fermentableInit) {
+    if (row.f_added == 4) {
+     $('#bottle_priming_total').val(row.f_amount * 1000);    // Prevent clearing
+     $('#bottle_priming_sugar').val(row.f_name);
+    }
+    if (row.f_added == 5) {
+     $('#keg_priming_total').val(row.f_amount * 1000);
+     $('#keg_priming_sugar').val(row.f_name);
+    }
+   }
+   // Check supplies.
+   if ((((dataRecord.inventory_reduced <= 2) && (row.f_added <= 1)) ||  // Mash or boil
+        ((dataRecord.inventory_reduced <= 3) && (row.f_added == 2)) ||  // Primary
+        ((dataRecord.inventory_reduced <= 5) && (row.f_added == 3)) ||  // Secondary or Tertiary
+        ((dataRecord.inventory_reduced <= 6) && (row.f_added == 4)) ||  // Bottle
+        ((dataRecord.inventory_reduced <= 6) && (row.f_added == 5))) && row.f_inventory < row.f_amount) {
+    ok_fermentables = 0;
+   }
+   if (row.f_added == 0 && (row.f_type == 0 || row.f_type == 4) && row.f_color < 50) { // Mash and Grain/Adjunct and Color < 50
+    lintner += row.f_diastatic_power * row.f_amount;
+   }
+  }
+  fermentableInit = 0;
+  $('#ferm_lintner').val(Math.round(parseFloat(lintner / mashkg)));
+  $('#mash_kg').val(mashkg);
+  console.log('calcFermentables() supplies:' + ok_fermentables + ' moutsuiker:' + Round(sugarsm, 3) + '/' + Round(sugarsf, 3));
+  to_100 = my_100;
+
+  if (mvol > 0) {
+   v = s / sugardensity + mvol;
+   s = 1000 * s / (v * 10); //deg. Plato
+   est_mash_sg = Round(plato_to_sg(s), 5);
+   $('#est_mash_sg').val(est_mash_sg);
+  }
+
+  // Estimate total recipe OG.
+  dataRecord.est_og = estimate_sg(sugarsf + addedS, parseFloat(dataRecord.batch_size));
+  $('#est_og').val(dataRecord.est_og);
+  $('#est_og2').val(dataRecord.est_og);
+  org = dataRecord.est_og;
+
+  // Estimate SG in kettle after boil
+  aboil_sg = estimate_sg(sugarsf, parseFloat(dataRecord.batch_size));
+  $('#est_og3').val(aboil_sg);
+
+  // Estimate SG in kettle before boil
+  preboil_sg = estimate_sg(sugarsm, parseFloat(dataRecord.boil_size));
+  $('#est_pre_sg').val(preboil_sg);
+
+  // Recalculate volumes.
+  aboil_volume = parseFloat(dataRecord.batch_size);
+  if (dataRecord.brew_aboil_volume > 0)
+   aboil_volume = dataRecord.brew_aboil_volume / 1.04;     // volume @ 20 degrees
+  if (dataRecord.brew_fermenter_tcloss == 0) {
+   dataRecord.brew_fermenter_tcloss = dataRecord.eq_trub_chiller_loss;
+   $('#brew_fermenter_tcloss').val(dataRecord.brew_fermenter_tcloss);
+  }
+  dataRecord.brew_fermenter_volume = aboil_volume - dataRecord.brew_fermenter_tcloss + dataRecord.brew_fermenter_extrawater;
+  $('#brew_fermenter_volume').val(dataRecord.brew_fermenter_volume);
+  // Calculate SG in fermenter
+  ogx = dataRecord.brew_aboil_sg;
+  if (ogx < 1.002)
+   ogx = aboil_sg;
+  topw = dataRecord.brew_fermenter_extrawater;
+
+  if (dataRecord.brew_fermenter_volume > 0) {
+   sug = sg_to_plato(ogx) * dataRecord.brew_fermenter_volume * ogx / 100;  //kg of sugar in
+   sug += addedS; //kg
+
+   if ((dataRecord.brew_fermenter_volume * ogx + addedmass) > 0) {
+    pt = 100 * sug / (dataRecord.brew_fermenter_volume * ogx + addedmass + topw);
+    dataRecord.og = dataRecord.brew_fermenter_sg = Round(plato_to_sg(pt), 4);
+    $('#brew_fermenter_sg').val(dataRecord.brew_fermenter_sg);
+    // color
+    if (dataRecord.color_method == 4) {
+     dataRecord.brew_fermenter_color = Math.round(((pt / 8.6) * colorn) + (dataRecord.boil_time / 60));
+    } else if (dataRecord.color_method == 3) {
+     dataRecord.brew_fermenter_color = Math.round((4.46 * bv * sr) / (aboil_volume + topw) * colorh);
+    } else {
+     cw = colort / (aboil_volume + topw) * 8.34436;
+     dataRecord.brew_fermenter_color = kw_to_ebc(dataRecord.color_method, cw);
+    }
+    $('#brew_fermenter_color').val(dataRecord.brew_fermenter_color);
+    scolor = ebc_to_color(dataRecord.brew_fermenter_color);
+    $('#bcolorf').show();
+    document.getElementById('bcolorf').style.background = scolor;
+   }
+  } else {
+   // Negative volume
+   dataRecord.brew_fermenter_sg = dataRecord.brew_fermenter_color = 0;
+   $('#brew_fermenter_sg').val(0);
+   $('#brew_fermenter_color').val(0);
+   $('#bcolorf').hide();
+  }
+
+  // Color of the wort
+  if (dataRecord.color_method == 4) {
+   color = Math.round(((sg_to_plato(dataRecord.est_og) / 8.6) * colorn) + (dataRecord.boil_time / 60));
+  } else if (dataRecord.color_method == 3) {      // Hans Halberstadt
+   color = Math.round((4.46 * bv * sr) / parseFloat(dataRecord.batch_size) * colorh);
+  } else {
+   cw = colort / parseFloat(dataRecord.batch_size) * 8.34436;
+   color = kw_to_ebc(dataRecord.color_method, cw);
+  }
+  dataRecord.est_color = color;
+  $('#est_color').val(color);
+  $('#est_color2').val(color);
+  scolor = ebc_to_color(color);
+  document.getElementById('bcolor').style.background = scolor;
+  document.getElementById('bcolor2').style.background = scolor;
+
+  // Progress bars
+  pmalts = mashkg / dataRecord.eq_mash_max * 100;
+  $('#perc_malts').jqxProgressBar('val', pmalts);
+  $('#perc_sugars').jqxProgressBar('val', psugar);
+  $('#perc_cara').jqxProgressBar('val', pcara);
+  calcStage();
+
+  // Calculate estimated svg.
+  svg = 0; // default.
+  initcells = 0;
+  for (i = 0; i < dataRecord.yeasts.length; i++) {
+   row = dataRecord.yeasts[i];
+   if (row.y_use == 0) {   // Primary
+    if (parseFloat(row.y_attenuation) > svg)
+     svg = parseFloat(row.y_attenuation);    // Take the highest if multiple yeasts.
+    if (row.y_form == 0)
+     initcells += (parseFloat(row.y_cells) / 1000000000) * parseFloat(row.y_amount) * (dataRecord.starter_viability / 100);
+    else
+     initcells += (parseFloat(row.y_cells) / 1000000) * parseFloat(row.y_amount) * (dataRecord.starter_viability / 100);
+   }
+   // TODO: brett in secondary ??
+   if ((((dataRecord.inventory_reduced <= 3) && (row.y_use == 0)) ||  // Primary
+        ((dataRecord.inventory_reduced <= 4) && (row.y_use == 1)) ||  // Secondary
+        ((dataRecord.inventory_reduced <= 5) && (row.y_use == 2)) ||  // Tertiary
+        ((dataRecord.inventory_reduced <= 6) && (row.y_use == 3))) && // Bottle
+        (row.y_inventory < row.y_amount)) {
+    ok_yeasts = 0;
+   }
+  }
+  calcSupplies();
+  if (svg == 0)
+   svg = 77;
+  if ((mashkg > 0) && (infuse > 0) && (mashtime > 0) && (mashtemp > 0)) {
+   dataRecord.est_fg = estimate_fg(psugar, pcara, infuse / mashkg, mashtime, mashtemp, svg, dataRecord.est_og);
+  } else {
+   dataRecord.est_fg = estimate_fg(psugar, pcara, 0, 0, 0, svg, dataRecord.est_og);
+  }
+  $('#est_fg').val(dataRecord.est_fg);
+  $('#est_fg2').val(dataRecord.est_fg);
+  $('#est_fg3').val(dataRecord.est_fg);
+  fig = dataRecord.est_fg;
+
+  dataRecord.est_abv = abvol(dataRecord.est_og, dataRecord.est_fg);
+  $('#est_abv').val(dataRecord.est_abv);
+  $('#est_abv2').val(dataRecord.est_abv);
+
+  // Calculate the final svg if available use the real value.
+  if ((dataRecord.stage >= 6) && (dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) {
+   svg = calc_svg(dataRecord.brew_fermenter_sg, dataRecord.fg);
+   org = dataRecord.brew_fermenter_sg;
+   fig = dataRecord.fg;
+  }
+
+  $('#yeast_cells').val(initcells);
+  $('#need_cells').val(getNeededYeastCells());
+
+  // Calculate the calories in kcal/l (from brouwhulp)
+  alc = 1881.22 * fig * (org - fig) / (1.775 - org);
+  sug = 3550 * fig * (0.1808 * org + 0.8192 * fig - 1.0004);
+  $('#kcal').val(Math.round((alc + sug) / (12 * 0.0295735296)));
+ };
+
+ function calcMash() {
+
+  var h, m, infused = 0, mashtime = 0, mashvol = 0, vol, i, j, n, a, b, row, temp;
+  var lasttemp = 18.0;
+  var graintemp = 18.0;
+  var tuntemp = 18.0;
+
+  if (dataRecord.mashs.length && (mashkg > 0)) {
+   console.log('calcMash()');
+   for (i = 0; i < dataRecord.mashs.length; i++) {
+    row = dataRecord.mashs[i];
+    if (row.step_type == 0) { // Infusion
+     if (i == 0) {
+      // First mash step, temperature from the mashtun and malt.
+      n = 20; // tun is preheated.
+      tuntemp = row.step_temp;
+      for (j = 0; j < n; j++) {
+       a = mashkg * graintemp * SpecificHeatMalt + dataRecord.eq_tun_weight * tuntemp * dataRecord.eq_tun_specific_heat;
+       b = row.step_temp * (dataRecord.eq_tun_weight * dataRecord.eq_tun_specific_heat + row.step_infuse_amount * SpecificHeatWater + mashkg * SpecificHeatMalt) - SlakingHeat * mashkg;
+       if (row.step_infuse_amount > 0) {
+        temp = (b - a) / (row.step_infuse_amount * SpecificHeatWater);
+       } else {
+        temp = 99;
+       }
+       tuntemp += (temp - tuntemp) / 2;
+       row.step_infuse_temp = Round(temp, 6);
+      }
+      //console.log('init infuse temp: ' + row.step_infuse_temp);
+     } else {
+      // Calculate amount of infusion water.
+      row.step_infuse_amount = infusionVol(infused, mashkg, row.step_infuse_temp, row.step_temp, lasttemp);
+      //console.log('vol: ' + row.step_infuse_amount + ' temp: ' + row.step_infuse_temp);
+     }
+     infused += parseFloat(row.step_infuse_amount);
+    } else if (row.step_type == 1) { // Temperature
+     if (i > 0)
+      row.step_infuse_amount = 0;
+     row.step_infuse_temp = 0;
+    } else if (row.step_type == 2) { // Decoction
+     row.step_infuse_amount = decoctionVol(infused, row.step_temp, lasttemp);
+     row.step_infuse_temp = 99;
+    }
+    row.step_volume = infused;
+    //console.log(i + ' type: ' + row.step_type + ' volume: ' + row.step_infuse_amount + ' temp: ' + row.step_infuse_temp);
+    lasttemp = row.step_temp;
+    mashtime += row.step_time + row.ramp_time;
+    row.step_wg_ratio = Round(infused / mashkg, 6);
+    $('#mashGrid').jqxGrid('updaterow', i, row);
+   }
+  }
+  if ((dataRecord.w1_amount + dataRecord.w2_amount) == 0) {
+    dataRecord.w1_amount = infused;
+    $('#w1_amount').val(infused);
+    console.log("calcMash() fixed water 1 to " + infused);
+  }
+  mashvol = Round(mashkg * MaltVolume + infused, 6);
+  $('#est_mashvol').val(mashvol);
+  h = Math.floor(mashtime / 60);
+  m = Math.floor(mashtime - (h * 60));
+  if (h < 10)
+    h = '0' + h;
+  if (m < 10)
+    m = '0' + m;
+  $('#est_mashtime').val(h + ':' + m);
+  // Estimated needed sparge water corrected for the temperature.
+  spoelw = Round((dataRecord.boil_size - infused + (mashkg * my_grain_absorbtion) + dataRecord.eq_lauter_deadspace) * 1.03, 6);
+  $('#brew_sparge_est').val(spoelw);
+ }
+
+ function getNeededYeastCells() {
+
+  var plato, volume, sg = dataRecord.brew_fermenter_sg;
+  if (sg <= 1.0001 && dataRecord.fg > 1.000)
+   sg = dataRecord.fg;
+  else if (sg <= 1.0001)
+   sg = dataRecord.est_og;
+  plato = sg_to_plato(sg);
+
+  volume = dataRecord.brew_fermenter_volume;
+  if (volume <= 0)
+   volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss;
+
+  return dataRecord.yeast_pitchrate * volume * plato;
+ }
+
+ function hopFlavourContribution(bt, vol, use, amount) {
+  var result;
+
+  if (use == 4 || use == 5) // Whirlpool or Dry-hop
+   return 0;
+  if (use == 1) { // First wort
+   result = 0.15;          // assume 15% flavourcontribution for fwh
+  } else if (bt > 50) {
+   result = 0.10;          // assume 10% flavourcontribution as a minimum
+  } else {
+   result = 15.25 / (6 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 21) / 6, 2));
+   if (result < 0.10)
+    result = 0.10;  // assume 10% flavourcontribution as a minimum
+  }
+  return (result * amount * 1000) / vol;
+ }
+
+ function hopAromaContribution(bt, vol, use, amount) {
+  var result = 0;
+
+  if (use == 5) { // Dry hop
+   result = 1.33;
+  } else if (use == 4) { // Whirlpool
+   if (bt > 30)
+    bt = 30; // Max 30 minutes
+   result = 0.62 * bt / 30;
+  } else if (bt > 20) {
+   result = 0;
+  } else if (bt > 7.5) {
+   result = 10.03 / (4 * Math.sqrt(2 * Math.PI)) * Math.exp(-0.5 * Math.pow((bt - 7.5) / 4, 2));
+  } else if (use == 2) {  // Boil
+   result = 1;
+  } else if (use == 3) {  // Aroma
+   result = 1.2;
+  }
+  return (result * amount * 1000) / vol;
+ }
+
+ function calcIBUs() {
+  var total_ibus = 0, ferm_ibus = 0, rows = {}, i, row;
+  hop_aroma = hop_flavour = 0;
+  if (!(rows = $('#hopGrid').jqxGrid('getrows'))) {
+   return;
+  }
+  ok_hops = 1;
+  for (i = 0; i < rows.length; i++) {
+   row = rows[i];
+   total_ibus += toIBU(row.h_useat, row.h_form, preboil_sg, parseFloat(dataRecord.batch_size),
+    parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method,
+    dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6);
+   ferm_ibus += toIBU(row.h_useat, row.h_form, preboil_sg,
+    parseFloat(dataRecord.brew_fermenter_volume) + parseFloat(dataRecord.brew_fermenter_tcloss),
+    parseFloat(row.h_amount), parseFloat(row.h_time), parseFloat(row.h_alpha), dataRecord.ibu_method,
+    dataRecord.brew_whirlpool9, dataRecord.brew_whirlpool7, dataRecord.brew_whirlpool6);
+   hop_flavour += hopFlavourContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount));
+   hop_aroma += hopAromaContribution(parseFloat(row.h_time), parseFloat(dataRecord.batch_size), row.h_useat, parseFloat(row.h_amount));
+   if ((((dataRecord.inventory_reduced <= 2) && (row.h_useat <= 4)) ||  // Mash, FW, Boil, Aroma, Whirlpool
+        ((dataRecord.inventory_reduced <= 6) && (row.h_useat == 5))) && // Dry-hop
+        (row.h_inventory < row.h_amount))
+    ok_hops = 0;
+  }
+  total_ibus = Round(total_ibus, 1);
+  ferm_ibus = Round(ferm_ibus, 1);
+  hop_flavour = Round(hop_flavour * 100 / 5, 1);
+  hop_aroma = Round(hop_aroma * 100 / 6, 1);
+  if (hop_flavour > 100)
+   hop_flavour = 100;
+  if (hop_aroma > 100)
+   hop_aroma = 100;
+  console.log('calcIBUs(): ' + total_ibus + ' flavour: ' + hop_flavour + ' aroma: ' + hop_aroma +
+               ' fermenter:' + ferm_ibus + ' supplies:' + ok_hops);
+  dataRecord.est_ibu = total_ibus;
+  $('#est_ibu').val(total_ibus);
+  $('#est_ibu2').val(total_ibus);
+  $('#hop_flavour').jqxProgressBar('val', hop_flavour);
+  $('#hop_aroma').jqxProgressBar('val', hop_aroma);
+  $('#brew_fermenter_ibu').val(ferm_ibus);
+  calcStage();
+  calcSupplies();
+ };
+
+ /*
+  * http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
+  *
+  * stype: 0=stirred, 1=shaken, 2=simple
+  * totcells: initial cells
+  * egrams: gram extract
+  */
+ function getGrowthRate(stype, totcells, egrams) {
+
+  /* Cells per grams extract (B/g) */
+  var cpe = totcells / egrams;
+
+  if (cpe > 3.5)
+   return 0;       // no growth
+  if (stype == 2)
+   return 0.4;     // simple starter
+  if (stype == 1)
+   return 0.62;    // shaken starter
+  if (cpe <= 1.4)  // stirred starter
+   return 1.4;
+  return 2.33 - (.67 * cpe);
+ };
+
+ function calcStep(svol, stype, start) {
+
+  var gperpoint = 2.72715,  //number of grams of extract per point of starter gravity per liter
+  prate = start / svol * 1000,
+  irate = Round(prate, 1),
+  egrams = (dataRecord.starter_sg - 1) * svol * gperpoint,
+  grate = getGrowthRate(stype, start, egrams),
+  ncells = Round(egrams * grate, 1),
+  totcells = parseFloat(ncells) + start;
+
+  return {
+   svol: svol,
+   irate: irate,
+   prate: Round(prate, 1),
+   ncells: ncells,
+   totcells: totcells,
+   growf: Round(ncells / start, 2)
+  };
+ }
+
+ function killstep2() {
+
+  dataRecord.prop2_volume = 0;
+  $('#prop2_volume').val(0);
+  $('#prop2_tcells').val(0);
+  $('#prop2_type,#prop2_volume,#prop2_irate,#prop2_ncells,#prop2_tcells,#prop2_growf').hide();
+  $('#r2_pmpt').show();
+ }
+
+ function killstep3() {
+
+  dataRecord.prop3_volume = 0;
+  $('#prop3_volume').val(0);
+  $('#prop3_tcells').val(0);
+  $('#prop3_type,#prop3_volume,#prop3_irate,#prop3_ncells,#prop3_tcells,#prop3_growf').hide();
+  $('#r3_pmpt').show();
+ }
+
+ function killstep4() {
+
+  dataRecord.prop4_volume = 0;
+  $('#prop4_volume').val(0);
+  $('#prop4_tcells').val(0);
+  $('#prop4_type,#prop4_volume,#prop4_irate,#prop4_ncells,#prop4_tcells,#prop4_growf').hide();
+  $('#r4_pmpt').show();
+ }
+
+ /*
+  * Calculate all starter steps.
+  * stype: final starter type: 0 = stirred, 1 = shaked, 2 = simple.
+  * start: initial cells in billions
+  * needed: needed cells in billions
+  *
+  * result: all values updated.
+  */
+ function calcSteps(stype, start, needed) {
+
+  var uvols = [20, 40, 60, 80, 100, 150, 200, 250, 375, 500, 625, 750, 875, 1000, 1250, 1500, 2000, 2500, 3000, 4000, 5000],
+      mvols = uvols.length, svol = 0, lasti = 0, result = {}, i;
+
+  /*
+   * If no values are set, auto calculate the starter.
+   */
+  if ((parseFloat($('#prop1_volume').jqxNumberInput('decimal')) + parseFloat($('#prop2_volume').jqxNumberInput('decimal')) +
+       parseFloat($('#prop3_volume').jqxNumberInput('decimal')) + parseFloat($('#prop4_volume').jqxNumberInput('decimal'))) == 0) {
+   // clear by default
+   for (i = 1; i < 5; i++) {
+    $('#prop' + i + '_type,#prop' + i + '_volume,#prop' + i + '_irate,#prop' + i + '_ncells,#prop' + i + '_tcells,#prop' + i + '_growf').hide();
+    $('#r' + i + '_pmpt').show();
+    $('#prop' + i + '_type').val(stype);
+    $('#prop' + i + '_volume').val(0);
+   }
+   if (start > needed) {
+    return; // no starter needed
+   }
+   $('#prop1_type,#prop1_volume,#prop1_irate,#prop1_ncells,#prop1_tcells,#prop1_growf').show();
+   $('#r1_pmpt').hide();
+   for (i = lasti; i <= mvols; i++) {
+    lasti = i;
+    svol = uvols[lasti];
+    result = calcStep(svol, stype, start);
+    if (result.irate < 25) {
+     // inocculation rate too low, backup one step and break out.
+     lasti = i - 1;
+     svol = uvols[lasti];
+     result = calcStep(svol, stype, start);
+     break;
+    }
+    if (result.totcells > needed || i == mvols) { // hit the target or loops done
+     break;
+    }
+   }
+   $('#prop1_volume').val(result.svol / 1000); // to liters
+   $('#prop1_irate').val(result.prate);
+   $('#prop1_ncells').val(result.ncells);
+   $('#prop1_tcells').val(result.totcells);
+   $('#prop1_growf').val(result.growf);
+   if (result.totcells > needed)
+    return; // hit the target
+
+   // second stage
+   $('#r2_pmpt').hide();
+   $('#prop2_type').val(stype);
+   $('#prop2_type,#prop2_volume,#prop2_irate,#prop2_ncells,#prop2_tcells,#prop2_growf').show();
+   for (i = lasti; i <= mvols; i++) {
+    lasti = i;
+    svol = uvols[lasti];
+    result = calcStep(svol, stype, $('#prop1_tcells').val());
+    if (result.irate < 25) {
+     lasti = i - 1;
+     svol = uvols[lasti];
+     result = calcStep(svol, stype, $('#prop1_tcells').val());
+     break;
+    }
+    if (result.totcells > needed || i == mvols) { // hit the target or loops done
+     break;
+    }
+   }
+   $('#prop2_volume').val(result.svol / 1000); // to liters
+   $('#prop2_irate').val(result.prate);
+   $('#prop2_ncells').val(result.ncells);
+   $('#prop2_tcells').val(result.totcells);
+   $('#prop2_growf').val(result.growf);
+   if (result.totcells > needed)
+    return; // hit the target
+
+   // third stage
+   $('#r3_pmpt').hide();
+   $('#prop3_type').val(stype);
+   $('#prop3_type,#prop3_volume,#prop3_irate,#prop3_ncells,#prop3_tcells,#prop3_growf').show();
+   for (i = lasti; i <= mvols; i++) {
+    lasti = i;
+    svol = uvols[lasti];
+    result = calcStep(svol, stype, $('#prop2_tcells').val());
+    if (result.irate < 25) {
+     lasti = i - 1;
+     svol = uvols[lasti];
+     result = calcStep(svol, stype, $('#prop2_tcells').val());
+     break;
+    }
+    if (result.totcells > needed || i == mvols) { // hit the target or loops done
+     break;
+    }
+   }
+   $('#prop3_volume').val(result.svol / 1000); // to liters
+   $('#prop3_irate').val(result.prate);
+   $('#prop3_ncells').val(result.ncells);
+   $('#prop3_tcells').val(result.totcells);
+   $('#prop3_growf').val(result.growf);
+   if (result.totcells > needed)
+    return; // hit the target
+
+   // fourth stage
+   $('#r4_pmpt').hide();
+   $('#prop4_type').val(stype);
+   $('#prop4_type,#prop4_volume,#prop4_irate,#prop4_ncells,#prop4_tcells,#prop4_growf').show();
+   for (i = lasti; i <= mvols; i++) {
+    lasti = i;
+    svol = uvols[lasti];
+    result = calcStep(svol, stype, $('#prop3_tcells').val());
+    if (result.totcells > needed || i == mvols) { // hit the target or loops done
+     $('#prop4_volume').val(result.svol / 1000); // to liters
+     $('#prop4_irate').val(result.prate);
+     $('#prop4_ncells').val(result.ncells);
+     $('#prop4_tcells').val(result.totcells);
+     $('#prop4_growf').val(result.growf);
+     return;
+    }
+   }
+  } else {
+   // recalculate
+   if (dataRecord.prop1_volume > 0) {
+    $('#r1_pmpt').hide();
+    $('#prop1_type,#prop1_volume,#prop1_irate,#prop1_ncells,#prop1_tcells,#prop1_growf').show();
+    result = calcStep($('#prop1_volume').val() * 1000, dataRecord.prop1_type, start);
+    $('#prop1_irate').val(result.prate);
+    $('#prop1_ncells').val(result.ncells);
+    $('#prop1_tcells').val(result.totcells);
+    $('#prop1_growf').val(result.growf);
+    if (result.totcells > needed) {
+     killstep2();
+     killstep3();
+     killstep4();
+    } else if (dataRecord.prop2_volume == 0) {
+     dataRecord.prop2_volume = dataRecord.prop1_volume; /* Extra step needed, start with the same size */
+     dataRecord.prop2_type = dataRecord.prop1_type;
+     $('#prop2_volume').val(dataRecord.prop2_volume);
+     $('#prop2_type').val(dataRecord.prop2_type);
+    }
+   }
+   if (dataRecord.prop2_volume > 0) {
+    $('#r2_pmpt').hide();
+    $('#prop2_type,#prop2_volume,#prop2_irate,#prop2_ncells,#prop2_tcells,#prop2_growf').show();
+    result = calcStep($('#prop2_volume').val() * 1000, dataRecord.prop2_type, $('#prop1_tcells').val());
+    $('#prop2_irate').val(result.prate);
+    $('#prop2_ncells').val(result.ncells);
+    $('#prop2_tcells').val(result.totcells);
+    $('#prop2_growf').val(result.growf);
+    if (result.totcells > needed) {
+     killstep3();
+     killstep4();
+    } else if (dataRecord.prop3_volume == 0) {
+     dataRecord.prop3_volume = dataRecord.prop2_volume; /* Extra step needed, start with the same size */
+     dataRecord.prop3_type = dataRecord.prop2_type;
+     $('#prop3_volume').val(dataRecord.prop3_volume);
+     $('#prop3_type').val(dataRecord.prop3_type);
+    }
+   }
+   if (dataRecord.prop3_volume > 0) {
+    $('#r3_pmpt').hide();
+    $('#prop3_type,#prop3_volume,#prop3_irate,#prop3_ncells,#prop3_tcells,#prop3_growf').show();
+    result = calcStep($('#prop3_volume').val() * 1000, dataRecord.prop3_type, $('#prop2_tcells').val());
+    $('#prop3_irate').val(result.prate);
+    $('#prop3_ncells').val(result.ncells);
+    $('#prop3_tcells').val(result.totcells);
+    $('#prop3_growf').val(result.growf);
+    if (result.totcells > needed) {
+     killstep4();
+    } else if (dataRecord.prop4_volume == 0) {
+     dataRecord.prop4_volume = dataRecord.prop3_volume; /* Extra step needed, start with the same size */
+     dataRecord.prop4_type = dataRecord.prop3_type;
+     $('#prop4_volume').val(dataRecord.prop4_volume);
+     $('#prop4_type').val(dataRecord.prop4_type);
+    }
+   }
+   if (dataRecord.prop4_volume > 0) {
+    $('#r4_pmpt').hide();
+    $('#prop4_type,#prop4_volume,#prop4_irate,#prop4_ncells,#prop4_tcells,#prop4_growf').show();
+    result = calcStep($('#prop4_volume').val() * 1000, dataRecord.prop4_type, $('#prop3_tcells').val());
+    $('#prop4_irate').val(result.prate);
+    $('#prop4_ncells').val(result.ncells);
+    $('#prop4_tcells').val(result.totcells);
+    $('#prop4_growf').val(result.growf);
+   }
+  }
+ }
+
+ function calcYeast() {
+
+  // Calculate needed cells.
+  var plato, volume, rows, rowscount, row, i, needed, use_cells, sg = dataRecord.brew_fermenter_sg;
+
+  if (sg <= 1.0001 && dataRecord.fg > 1.000)
+   sg = dataRecord.fg;
+  else if (sg <= 1.0001)
+   sg = dataRecord.est_og;
+  plato = sg_to_plato(sg);
+
+  volume = dataRecord.brew_fermenter_volume;
+  if (volume > 0) {
+   if (dataRecord.brew_fermenter_extrawater > 0)
+    volume += dataRecord.brew_fermenter_extrawater;
+  } else {
+   volume = dataRecord.batch_size - dataRecord.eq_trub_chiller_loss;
+  }
+
+  // Also in calcFermentables()
+  $('#yeast_cells').val(initcells);
+
+  if (!(rows = $('#yeastGrid').jqxGrid('getrows'))) {
+   return; // grid not yet loaded.
+  }
+  rowscount = dataRecord.yeasts.length;
+  if (rowscount == 0)
+   return; // no yeast in recipe
+
+  $('.primary_dry').hide();
+  $('.primary_liquid').hide();
+
+  var maybe_starter = 0;
+  var pitchrate = 0.75;    // Yeast pitch rate default
+  for (i = 0; i < rowscount; i++) {
+   row = dataRecord.yeasts[i];
+   if (row.y_use == 0) { // primary
+    if (row.y_form == 1) {
+     // Dry yeast
+     $('.primary_dry').show();
+     console.log('dry yeast: ' + row.y_gr_hl_lo + '@' + row.y_sg_lo + '  ' + row.y_gr_hl_hi + '@' + row.y_sg_hi);
+     // Build the formule with the yeast parameters.
+     // Based on https://www.lallemandbrewing.com/en/canada/brewers-corner/brewing-tools/pitching-rate-calculator/
+     var og = row.y_sg_lo;
+     var f1 = row.y_gr_hl_lo / 100;
+     var f2 = Round(f1 / 5, 6);
+     // After a lot of try and error, study, the best thing to increase the pitch amount is actually
+     // use this simple formula by Lallemand. This is about the same as sugar weight increment in the wort.
+     var multiplier = (sg <= og) ? f1 : (f1 + f2 * (sg - og) / 0.008);
+     console.log('sg: ' + sg + ' og: ' + og + ' f1: ' + f1 + ' f2: ' + f2 + ' multiplier: ' + multiplier);
+     // dataRecord.starter_viability
+     var yeast_grams = Round(volume * multiplier * (100 / dataRecord.starter_viability), 2);
+     $('#yeast_grams').val(yeast_grams);
+     var yeast_gr_hl = Round(yeast_grams / (volume * 0.01), 2);
+     $('#yeast_gr_hl').val(yeast_gr_hl);
+     //console.log('need ' + yeast_grams + ' grams, gr/hl: ' + yeast_gr_hl);
+
+    } else {
+     // Liquid yeast
+     $('.primary_liquid').show();
+     // pitchrate see https://www.brewersfriend.com/yeast-pitch-rate-and-starter-calculator/
+     // and http://braukaiser.com/blog/blog/2012/11/03/estimating-yeast-growth/
+     if (row.y_type == 0) { // lager yeast
+      pitchrate = 1.5;
+      if (dataRecord.est_og > 1.060)
+       pitchrate = 2.0;
+     } else if (row.y_type == 6) { // Kveik
+      pitchrate = 0.075;
+     } else {
+      pitchrate = 0.75;
+      if (dataRecord.est_og > 1.060)
+       pitchrate = 1.0;
+     }
+     if (dataRecord.yeast_pitchrate < 0.01) {
+      dataRecord.yeast_pitchrate = pitchrate;
+      $('#yeast_pitchrate').val(pitchrate);
+     }
+     maybe_starter = 1;
+    }
+   }
+  }
+
+  needed = Round(dataRecord.yeast_pitchrate * volume * plato, 1);
+  $('#need_cells').val(needed);
+  use_cells = initcells;
+  if (needed <= initcells)
+   maybe_starter = 0;
+  //console.log('calcYeast() pitchrate:' + dataRecord.yeast_pitchrate + ' start:' + initcells + ' needed:' + needed + ' volume:' + volume + ' maybe_starter:' + maybe_starter);
+
+  if (maybe_starter != dataRecord.starter_enable) {
+   dataRecord.starter_enable = maybe_starter;
+  }
+  if (maybe_starter)
+   $('#propagator').show();
+  else
+   $('#propagator').hide();
+
+  if (dataRecord.starter_enable) {
+
+   calcSteps(dataRecord.starter_type, initcells, needed);
+
+   for (i = 1; i < 5; i++) {
+    $('#r' + i + '_irate').html('');
+    $('#r' + i + '_growf').html('');
+    $('#r' + i + '_tcells').html('');
+    if (parseFloat($('#prop' + i + '_volume').val()) > 0) {
+     if ((parseFloat($('#prop' + i + '_irate').val()) < 25) || (parseFloat($('#prop' + i + '_irate').val()) > 100)) {
+      $('#r' + i + '_irate').html("<img src='images/dialog-error.png'>");
+     } else {
+      $('#r' + i + '_irate').html("<img src='images/dialog-ok-apply.png'>");
+     }
+     if (parseFloat($('#prop' + i + '_growf').val()) < 1)
+      $('#r' + i + '_growf').html("<img src='images/dialog-error.png'>");
+     if (($('#prop' + i + '_type').val() > 0) && (parseFloat($('#prop' + i + '_growf').val()) > 3))
+      $('#r' + i + '_growf').html("<img src='images/dialog-error.png'>");
+     if (parseFloat($('#prop' + i + '_tcells').val()) > needed)
+      $('#r' + i + '_tcells').html("<img src='images/dialog-ok-apply.png'>");
+     use_cells = parseFloat($('#prop' + i + '_tcells').val());
+    } else {
+     $('#r' + i + '_irate').html('');
+    }
+   }
+  }
+  $('#plato_cells').val(parseFloat(use_cells / (volume * plato)));
+ };
+
+ function whirlpoolHops() {
+  var row, i, time, rowscount = dataRecord.hops.length;
+  if (rowscount == 0)
+   return;
+  for (i = 0; i < rowscount; i++) {
+   row = dataRecord.hops[i];
+   if (row.h_useat == 4) {
+    time = parseFloat(dataRecord.brew_whirlpool9) + parseFloat(dataRecord.brew_whirlpool7) + parseFloat(dataRecord.brew_whirlpool6);
+    dataRecord.hops[i].h_time = time;
+    $('#hopGrid').jqxGrid('setcellvalue', i, 'h_time', time);
+   }
+  }
+ };
+
+ function calcMiscs() {
+
+  ok_miscs = 1;
+  var row, i, rowscount = dataRecord.miscs.length;
+  if (rowscount == 0)
+   return;
+  for (i = 0; i < rowscount; i++) {
+   row = dataRecord.miscs[i];
+   if ((((dataRecord.inventory_reduced <= 2) && (row.m_use_use <= 2)) ||  // Starter, Mash, Boil
+	((dataRecord.inventory_reduced <= 2) && (row.m_use_use == 6)) ||  // Sparge
+        ((dataRecord.inventory_reduced <= 3) && (row.m_use_use == 3)) ||  // Primary
+        ((dataRecord.inventory_reduced <= 5) && (row.m_use_use == 4)) ||  // Secondary, Teriary
+        ((dataRecord.inventory_reduced <= 6) && (row.m_use_use == 5))) && // Bottle
+        (row.m_inventory < row.m_amount)) {
+    ok_miscs = 0;
+   }
+  }
+  calcSupplies();
+ };
+
+ function GetBUGU() {
+  var gu = (dataRecord.est_og - 1) * 1000;
+  if (gu > 0)
+   return dataRecord.est_ibu / gu;
+  else
+   return 0.5;
+ }
+
+ function GetOptSO4Clratio() {
+   var BUGU = GetBUGU();
+   return (1.0 / (-1.2 * BUGU + 1.4));
+ }
+
+ function setWaterAgent(name, amount, use) {
+  var row, i, id, found = false, miscs, rows = $('#miscGrid').jqxGrid('getrows');
+  if (amount == 0) {
+   for (i = 0; i < rows.length; i++) {
+    row = rows[i];
+    if (row.m_name == name && row.m_use_use == use) {
+     id = $('#miscGrid').jqxGrid('getrowid', i);
+     $('#miscGrid').jqxGrid('deleterow', id);
+    }
+   }
+  } else {
+   for (i = 0; i < rows.length; i++) {
+    row = rows[i];
+    if (row.m_name == name && row.m_use_use == use) {
+     found = true;
+     $('#miscGrid').jqxGrid('setcellvalue', i, 'm_amount', amount / 1000);
+     break;
+    }
+   }
+   if (! found) {
+    miscs = new $.jqx.dataAdapter(miscInvSource, {
+     loadComplete: function() {
+      var record, i, row = {}, records = miscs.records;
+      for (i = 0; i < records.length; i++) {
+       record = records[i];
+       if (record.name == name) {
+        row['m_name'] = record.name;
+        row['m_amount'] = amount / 1000;
+        row['m_cost'] = record.cost;
+        row['m_type'] = record.type;
+        row['m_use_use'] = use;
+        row['m_time'] = 0;
+        row['m_amount_is_weight'] = record.amount_is_weight;
+        row['m_inventory'] = record.inventory;
+        row['m_avail'] = 1;
+        $('#miscGrid').jqxGrid('addrow', null, row);
+       }
+      }
+     }
+    });
+    miscs.dataBind();
+    return;
+   }
+  }
+ }
+
+ function setRangeIndicator(ion, rangeCode) {
+  if ((rangeCode == 'laag') || (rangeCode == 'hoog'))
+   $('#wr_' + ion).html("<img src='images/dialog-error.png'><span style='vertical-align: top; font-size: 10px; font-style: italic;'>" + rangeCode + '</span>');
+  else
+   $('#wr_' + ion).html("<img src='images/dialog-ok-apply.png'>");
+ }
+
+ function mix(v1, v2, c1, c2) {
+  if ((v1 + v2) > 0) {
+   return ((v1 * c1) + (v2 * c2)) / (v1 + v2);
+  }
+  return 0;
+ }
+
+ function PartCO3(pH) {
+  var H = Math.pow(10, -pH);
+  return 100 * Ka1 * Ka2 / (H * H + H * Ka1 + Ka1 * Ka2);
+ }
+
+ function PartHCO3(pH) {
+  var H = Math.pow(10, -pH);
+  return 100 * Ka1 * H / (H * H + H * Ka1 + Ka1 * Ka2);
+ }
+
+ function Charge(pH) {
+  return (-2 * PartCO3(pH) - PartHCO3(pH));
+ }
+
+ //Z alkalinity is the amount of acid (in mEq/l) needed to bring water to the target pH (Z pH)
+ function ZAlkalinity(pHZ) {
+  var C43 = Charge(4.3),
+  Cw = Charge(parseFloat($('#wg_ph').jqxNumberInput('decimal'))),
+  Cz = Charge(pHZ),
+  DeltaCNaught = -C43 + Cw,
+  CT = parseFloat($('#wg_total_alkalinity').jqxNumberInput('decimal')) / 50 / DeltaCNaught,
+  DeltaCZ = -Cz + Cw;
+  return CT * DeltaCZ;
+ }
+
+ //Z Residual alkalinity is the amount of acid (in mEq/l) needed to bring the water in the mash to the target pH (Z pH)
+ function ZRA(pHZ) {
+
+  var Magn, Z, Calc = parseFloat($('#wg_calcium').jqxNumberInput('decimal')) / (MMCa / 2);
+  Magn = parseFloat($('#wg_magnesium').jqxNumberInput('decimal')) / (MMMg / 2);
+  Z = ZAlkalinity(pHZ);
+  return Z - (Calc / 3.5 + Magn / 7);
+ }
+
+ function BufferCapacity(di_ph, acid_to_ph_57, ebc, graintype) {
+  C1 = 0;
+  if ((di_ph != 5.7) && ((acid_to_ph_57 < - 0.1) || (acid_to_ph_57 > 0.1))) {
+      C1 = acid_to_ph_57 / (di_ph - 5.7);
+  } else {
+      // If the acid_to_ph_5.7 is unknown from the maltster, guess the required acid.
+      switch (graintype) {
+       case 0:                                 // Base, Special, Kilned
+       case 3:
+       case 5: C1 = 0.014 * ebc - 34.192;
+               break;
+       case 2: C1 = -0.0597 * ebc - 32.457;    // Crystal
+               break;
+       case 1: C1 = 0.0107 * ebc - 54.768;     // Roast
+               break;
+       case 4: C1 = -149;                      // Sour malt
+               break;
+      }
+  }
+  return C1;
+ }
+
+ function ProtonDeficit(pHZ) {
+
+  var i, C1, x, Result = ZRA(pHZ) * parseFloat($('#wg_amount').jqxNumberInput('decimal'));
+  // proton deficit for the grist
+  if (( $('#fermentableGrid').jqxGrid('getrows'))) {
+   for (i = 0; i < dataRecord.fermentables.length; i++) {
+    row = dataRecord.fermentables[i];
+    if (row.f_added == 0 && row.f_graintype != 6) { // Added == Mash && graintype != No Malt
+     C1 = BufferCapacity(row.f_di_ph, row.f_acid_to_ph_57, row.f_color, row.f_graintype);
+     x = C1 * (pHZ - row.f_di_ph);   // AcidRequired(ZpH)
+     Result += x * row.f_amount;
+    }
+   }
+  } else {
+   error_count++;
+   if (error_count < 5)
+    console.log('ProtonDeficit(' + pHZ + ') invalid grist, return ' + Result);
+  }
+  return Result;
+ }
+
+ function MashpH() {
+
+  var n = 0, pH = 5.4, deltapH = 0.001, deltapd = 0.1, pd = ProtonDeficit(pH);
+  while (((pd < -deltapd) || (pd > deltapd)) && (n < 2000)) {
+   n++;
+   if (pd < -deltapd)
+    pH -= deltapH;
+   else if (pd > deltapd)
+    pH += deltapH;
+   pd = ProtonDeficit(pH);
+  }
+  pH = Round(pH, 6);
+  //console.log('MashpH() n: ' + n + ' pH: ' + pH);
+  return pH;
+ }
+
+ function calcWater() {
+
+  /* Can be called during loading and building the screens */
+  if (! data_loaded) {
+   console.log('calcWater() failsave');
+   return;
+  }
+
+  var liters = 0,
+  calcium = 0,
+  magnesium = 0,
+  sodium = 0,
+  total_alkalinity = 0,
+  chloride = 0,
+  sulfate = 0,
+  ph = 0,
+  RA = 0,
+  frac = 0,
+  TpH = 0,
+  protonDeficit = 0,
+  AT, /*BT,*/
+  r1d, r2d, f1d, f2d, f3d,
+  deltapH, deltapd, pd, n,
+  Res;
+
+  if (dataRecord.w1_name == '') {
+   return;
+  }
+
+  $('#w1_hardness').val(Hardness(dataRecord.w1_calcium, dataRecord.w1_magnesium));
+  $('#w1_ra').val(ResidualAlkalinity(dataRecord.w1_total_alkalinity, dataRecord.w1_calcium, dataRecord.w1_magnesium));
+
+  // If there is a dillute water source, mix the waters.
+  if ((dataRecord.w2_name != '') && (dataRecord.w2_name != 'Geen mengwater')) {
+   liters = dataRecord.w1_amount + dataRecord.w2_amount;
+   calcium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_calcium, dataRecord.w2_calcium);
+   magnesium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_magnesium, dataRecord.w2_magnesium);
+   sodium = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sodium, dataRecord.w2_sodium);
+   chloride = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_chloride, dataRecord.w2_chloride);
+   sulfate = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_sulfate, dataRecord.w2_sulfate);
+   total_alkalinity = mix(dataRecord.w1_amount, dataRecord.w2_amount, dataRecord.w1_total_alkalinity, dataRecord.w2_total_alkalinity);
+   ph = -Math.log10(((Math.pow(10, -dataRecord.w1_ph) * dataRecord.w1_amount) + (Math.pow(10, -dataRecord.w2_ph) * dataRecord.w2_amount)) / liters);
+   $('#w2_hardness').val(Hardness(dataRecord.w2_calcium, dataRecord.w2_magnesium));
+   $('#w2_ra').val(ResidualAlkalinity(dataRecord.w2_total_alkalinity, dataRecord.w2_calcium, dataRecord.w2_magnesium));
+  } else {
+   liters = dataRecord.w1_amount;
+   calcium = dataRecord.w1_calcium;
+   magnesium = dataRecord.w1_magnesium;
+   sodium = dataRecord.w1_sodium;
+   chloride = dataRecord.w1_chloride;
+   sulfate = dataRecord.w1_sulfate;
+   total_alkalinity = dataRecord.w1_total_alkalinity;
+   ph = dataRecord.w1_ph;
+  }
+  var bicarbonate = Bicarbonate(total_alkalinity, ph);
+
+  /* Save mixed water ions for later */
+  var wg_calcium = calcium;
+  var wg_sodium = sodium;
+  var wg_total_alkalinity = total_alkalinity;
+  var wg_chloride = chloride;
+  var wg_sulfate = sulfate;
+  var wg_bicarbonate = bicarbonate;
+
+  dataRecord.wg_amount = liters;
+  dataRecord.wg_ph = ph;
+
+  $('#wg_amount').val(liters);
+  $('#wg_calcium').val(Round(calcium, 1));
+  $('#wg_magnesium').val(Round(magnesium, 1));
+  $('#wg_sodium').val(Round(sodium, 1));
+  $('#wg_bicarbonate').val(Round(bicarbonate, 1));
+  $('#wg_total_alkalinity').val(Round(total_alkalinity, 1));
+  $('#wg_chloride').val(Round(chloride, 1));
+  $('#wg_sulfate').val(Round(sulfate, 1));
+  $('#wg_ph').val(Round(ph, 2));
+  $('#wg_hardness').val(Round(Hardness(calcium, magnesium), 1));
+  $('#wg_ra').val(Round(ResidualAlkalinity(total_alkalinity, calcium, magnesium), 1));
+
+  var mash_ph = Round(MashpH(), 3);
+  console.log('Distilled water mash pH: ' + mash_ph);
+
+  /* Calculate Salt additions */
+  if (liters > 0) {
+   calcium += (parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 +
+    parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000 +
+    parseFloat($('#wa_caco3').jqxNumberInput('decimal')) * MMCa / MMCaCO3 * 1000) / liters;
+   magnesium += (parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4 * 1000 +
+    parseFloat($('#wa_mgcl2').jqxNumberInput('decimal')) * MMMg / MMMgCl2 * 1000) / liters;
+   sodium += (parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000 +
+    parseFloat($('#wa_nahco3').jqxNumberInput('decimal')) * MMNa / MMNaHCO3 * 1000) / liters;
+   sulfate += (parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 * 1000 +
+    parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 * 1000) / liters;
+   chloride += (2 * parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 * 1000 +
+    parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl * 1000 +
+    parseFloat($('#wa_mgcl2').jqxNumberInput('decimal')) * MMCl / MMMgCl2 * 1000) / liters;
+   bicarbonate += (parseFloat($('#wa_nahco3').jqxNumberInput('decimal')) * MMHCO3 / MMNaHCO3 * 1000 +
+    parseFloat($('#wa_caco3').jqxNumberInput('decimal')) / 3 * MMHCO3 / MMCaCO3 * 1000) / liters;
+  }
+
+  if (dataRecord.wa_acid_name < 0 || dataRecord,wa_acid_name >= AcidTypeData.length) {
+   $('#wa_acid_name').val(0);
+   dataRecord.wa_acid_name = 0;
+   dataRecord.wa_acid_perc = AcidTypeData[0].AcidPrc;
+   $('#wa_acid_perc').val(AcidTypeData[0].AcidPrc);
+  }
+  if (last_acid == '')
+   last_acid = AcidTypeData[dataRecord.wa_acid_name].nl;
+
+  if (parseFloat(dataRecord.wa_acid_perc) == 0) {
+   dataRecord.wa_acid_perc = AcidTypeData[AT].AcidPrc;
+   $('#wa_acid_perc').val(AcidTypeData[AT].AcidPrc);
+  }
+
+  AT = dataRecord.wa_acid_name;
+
+  /* Note that the next calculations do not correct the pH change by the added salts.
+     This pH change is at most 0.1 pH and is a minor difference in Acid amount. */
+
+  if (dataRecord.calc_acid) {
+   /* Auto calculate pH */
+   $('.c_mashph').show();
+   TpH = parseFloat(dataRecord.mash_ph);
+   protonDeficit = ProtonDeficit(TpH);
+   //console.log('calc_acid tgt: ' + TpH + ' protonDeficit: ' + protonDeficit);
+   if (protonDeficit > 0) { // Add acid
+    frac = CalcFrac(TpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
+    Acid = protonDeficit / frac;
+    Acid *= AcidTypeData[AT].MolWt; // mg
+    Acidmg = Acid;
+    var RealSG = Round(((AcidTypeData[AT].AcidSG - 1000) * (parseFloat(dataRecord.wa_acid_perc) / 100)) + 1000, 2);
+    Acid /= RealSG;
+    Acid /= AcidTypeData[AT].AcidPrc / 100;
+    Acid = Round(Acid, 2);
+    console.log('Mash auto Acid final ml: ' + Acid);
+    $('#wa_acid').val(Acid);
+    setWaterAgent(AcidTypeData[AT].nl, Acid, 1);
+
+    bicarbonate = bicarbonate - protonDeficit * frac / liters;
+    total_alkalinity = bicarbonate * 50 / 61;
+   }
+   ph = TpH;
+   dataRecord.wb_ph = ph;
+   $('#wb_ph').val(Round(ph, 2));
+   $('#est_mash_ph').val(Round(ph, 2));
+  } else {
+   /* Manual calculate pH */
+   $('.c_mashph').hide();
+   console.log('calc_acid no');
+   pHa = Round(ph, 3); // Adjusted water pH
+   // Then calculate the new pH with added acids and malts
+   console.log('Mash pH: ' + pHa);
+   Acid  = AcidTypeData[AT].AcidSG * (parseFloat(dataRecord.wa_acid_perc) / 100); // ml
+   Acid *= parseFloat($('#wa_acid').jqxNumberInput('decimal'));
+   Acid /= AcidTypeData[AT].MolWt;  // mg
+   Acidmg = Acid;
+
+   //find the pH where the protondeficit = protondeficit by the acid
+   frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
+   protonDeficit = Round(Acid * frac, 3);
+   //console.log('protonDeficit Acid: ' + protonDeficit + ' frac: ' + frac + ' pH: ' + pHa);
+
+   deltapH = 0.001;
+   deltapd = 0.1;
+   pd = Round(ProtonDeficit(pHa), 6);
+   n = 0;
+   while (((pd < (protonDeficit - deltapd)) || (pd > (protonDeficit + deltapd))) && (n < 4000)) {
+     n++;
+     if (pd < (protonDeficit - deltapd))
+      pHa -= deltapH;
+     else if (pd > (protonDeficit + deltapd))
+      pHa += deltapH;
+     frac = CalcFrac(pHa, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
+     protonDeficit = Acid * frac;
+     pd = ProtonDeficit(pHa);
+   }
+   //console.log('n: ' + n + ' pd: ' + pd + ' protonDeficit: ' + protonDeficit + ' frac: ' + frac + ' pHa: ' + pHa);
+   bicarbonate = wg_bicarbonate - protonDeficit * frac / liters;
+   total_alkalinity = bicarbonate * 50 / 61;
+   ph = pHa;
+   $('#wb_ph').val(Round(ph, 2));
+   $('#est_mash_ph').val(Round(ph, 2));
+  }
+
+  if ((AT == 3) && (liters > 0)) {        // Sulfuric / Zwavelzuur
+   RA = parseFloat($('#wa_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 +
+        parseFloat($('#wa_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 +
+        Acidmg / 1000 * MMSO4 / (MMSO4 + 2);
+   RA = 1000 * RA / liters;
+   sulfate = wg_sulfate + RA;      // Not add to sulfate??
+  } else if ((AT == 1) && (liters > 0)) { // Hydrochloric, Zoutzuur
+   RA = parseFloat($('#wa_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 +
+        parseFloat($('#wa_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl +
+        Acidmg / 1000 * MMCl / (MMCl + 1);
+   RA = 1000 * RA / liters;
+   chloride = wg_chloride + RA;
+  }
+
+  var BUGU = GetBUGU();
+  $('#tgt_bu').val(Round(BUGU, 2));
+  // From brouwhulp.
+  if (BUGU < 0.32)
+   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig en zoet</span>");
+  else if (BUGU < 0.43)
+   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig, zoet</span>");
+  else if (BUGU < 0.52)
+   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Evenwichtig</span>");
+  else if (BUGU < 0.63)
+   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht hoppig, bitter</span>");
+  else
+   $('#wr_bu').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Extra hoppig, zeer bitter</span>");
+
+  // Sulfate to Chloride ratio (Palmer).
+  var OptSO4Clratio = GetOptSO4Clratio();
+  $('#tgt_so4_cl').val(Round(OptSO4Clratio, 1));
+  if (OptSO4Clratio < 0.4)
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Te moutig</span>");
+  else if (OptSO4Clratio < 0.6)
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer moutig</span>");
+  else if (OptSO4Clratio < 0.8)
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Moutig</span>");
+  else if (OptSO4Clratio < 1.5)
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Gebalanceerd</span>");
+  else if (OptSO4Clratio < 2.0)
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Licht bitter</span>");
+  else if (OptSO4Clratio < 4.0)
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Bitter</span>");
+  else if (OptSO4Clratio < 9.0)
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Zeer bitter</span>");
+  else
+   $('#wrt_so4_cl').html("<span style='vertical-align: top; font-size: 14px; font-style: italic;'>Te bitter</span>");
+  if (chloride > 0)
+   RA = sulfate / chloride;
+  else
+   RA = 10;
+  $('#got_so4_cl').val(Round(RA, 1));
+  Res = 'normaal';
+  if (RA < (0.8 * OptSO4Clratio))
+   Res = 'laag';
+  else if (RA > (1.2 * OptSO4Clratio))
+   Res = 'hoog';
+  setRangeIndicator('so4_cl', Res);
+
+  $('#wb_calcium').val(Round(calcium, 1));
+  $('#wb_magnesium').val(Round(magnesium, 1));
+  $('#wb_sodium').val(Round(sodium, 1));
+  $('#wb_sulfate').val(Round(sulfate, 1));
+  $('#wb_chloride').val(Round(chloride, 1));
+  $('#wb_bicarbonate').val(Round(bicarbonate, 1));
+  $('#wb_total_alkalinity').val(Round(total_alkalinity, 1));
+  $('#wb_hardness').val(Hardness(calcium, magnesium));
+  $('#wb_ra').val(ResidualAlkalinity(total_alkalinity, calcium, magnesium));
+
+  if (calcium < 40) {
+   setRangeIndicator('calcium', 'laag');
+  } else if (calcium > 150) {
+   setRangeIndicator('calcium', 'hoog');
+  } else {
+   setRangeIndicator('calcium', 'normaal');
+  }
+  if (magnesium < 5) {
+   setRangeIndicator('magnesium', 'laag');
+  } else if (magnesium > 40) {
+   setRangeIndicator('magnesium', 'hoog');
+  } else {
+   setRangeIndicator('magnesium', 'normaal');
+  }
+  if (sodium <= 150) {
+   setRangeIndicator('sodium', 'normaal');
+  } else {
+   setRangeIndicator('sodium', 'hoog');
+  }
+  // Both chloride and sulfate should be above 50 according to
+  // John Palmer. So the Cl/SO4 ratio calculation will work.
+  if (chloride <= 50) {
+   setRangeIndicator('chloride', 'laag');
+  } else if (chloride <= 150) {
+   setRangeIndicator('chloride', 'normaal');
+  } else {
+   setRangeIndicator('chloride', 'hoog');
+  }
+  if (sulfate <= 50) {
+   setRangeIndicator('sulfate', 'laag');
+  } else if (sulfate <= 400) {
+   setRangeIndicator('sulfate', 'normaal');
+  } else {
+   setRangeIndicator('sulfate', 'hoog');
+  }
+  // (cloride + sulfate) > 500 is too high
+  if ((chloride + sulfate) > 500) {
+   setRangeIndicator('chloride', 'hoog');
+   setRangeIndicator('sulfate', 'hoog');
+  }
+  if (ph < 5.2) {
+   setRangeIndicator('ph', 'laag');
+  } else if (ph > 5.6) {
+   setRangeIndicator('ph', 'hoog');
+  } else {
+   setRangeIndicator('ph', 'normaal');
+  }
+  if (bicarbonate > 250) {
+   setRangeIndicator('bicarbonate', 'hoog');
+  } else {
+   setRangeIndicator('bicarbonate', 'normaal');
+  }
+  calcSparge();
+  calcMiscs();
+  calcSupplies();
+ }
+
+ function calcSparge() {
+
+  /* Based on the work of ajDeLange. */
+  var ws_calcium, ws_magnesium, ws_total_alkalinity, ws_sodium, ws_chloride;
+  var ws_sulfate, ws_ph, ws_hardness, ws_ra;
+  var TargetpH = dataRecord.sparge_ph;
+  var Source_pH = 7.0;
+
+  // Select watersource or fallback to the first source.
+  if ((dataRecord.sparge_source == 1) && (dataRecord.w2_ph > 0.0)) { // Source 2
+    ws_calcium = dataRecord.w2_calcium;
+    ws_magnesium = dataRecord.w2_magnesium;
+    ws_total_alkalinity = dataRecord.w2_total_alkalinity;
+    ws_sodium = dataRecord.w2_sodium;
+    ws_chloride = dataRecord.w2_chloride;
+    ws_sulfate = dataRecord.w2_sulfate;
+    Source_pH = dataRecord.w2_ph;
+    $('#w2_button').jqxRadioButton({ checked: true });
+  } else if ((dataRecord.sparge_source == 2) && (dataRecord.w2_ph > 0.0)) { // Mixed
+    ws_calcium = dataRecord.wg_calcium;
+    ws_magnesium = dataRecord.wg_magnesium;
+    ws_total_alkalinity = dataRecord.wg_total_alkalinity;
+    ws_sodium = dataRecord.wg_sodium;
+    ws_chloride = dataRecord.wg_chloride;
+    ws_sulfate = dataRecord.wg_sulfate;
+    Source_pH = dataRecord.wg_ph;
+    $('#wg_button').jqxRadioButton({ checked: true });
+  } else {
+    ws_calcium = dataRecord.w1_calcium;
+    ws_magnesium = dataRecord.w1_magnesium;
+    ws_total_alkalinity = dataRecord.w1_total_alkalinity;
+    ws_sodium = dataRecord.w1_sodium;
+    ws_chloride = dataRecord.w1_chloride;
+    ws_sulfate = dataRecord.w1_sulfate;
+    Source_pH = dataRecord.w1_ph;
+    $('#w1_button').jqxRadioButton({ checked: true });
+  }
+
+  if (dataRecord.sparge_volume > 0) {
+   ws_calcium += (parseFloat($('#ss_cacl2').jqxNumberInput('decimal')) * MMCa / MMCaCl2 * 1000 +
+    parseFloat($('#ss_caso4').jqxNumberInput('decimal')) * MMCa / MMCaSO4 * 1000) / dataRecord.sparge_volume;
+   ws_magnesium += (parseFloat($('#ss_mgso4').jqxNumberInput('decimal')) * MMMg / MMMgSO4 * 1000 +
+    parseFloat($('#ss_mgcl2').jqxNumberInput('decimal')) * MMMg / MMMgCl2 * 1000) / dataRecord.sparge_volume;
+   ws_sodium += (parseFloat($('#ss_nacl').jqxNumberInput('decimal')) * MMNa / MMNaCl * 1000) / dataRecord.sparge_volume;
+   ws_sulfate += (parseFloat($('#ss_caso4').jqxNumberInput('decimal')) * MMSO4 / MMCaSO4 * 1000 +
+    parseFloat($('#ss_mgso4').jqxNumberInput('decimal')) * MMSO4 / MMMgSO4 * 1000) / dataRecord.sparge_volume;
+   ws_chloride += (2 * parseFloat($('#ss_cacl2').jqxNumberInput('decimal')) * MMCl / MMCaCl2 * 1000 +
+    parseFloat($('#ss_nacl').jqxNumberInput('decimal')) * MMCl / MMNaCl * 1000 +
+    parseFloat($('#ss_mgcl2').jqxNumberInput('decimal')) * MMCl / MMMgCl2 * 1000) / dataRecord.sparge_volume;
+  }
+
+  /* Show the spargewate with salt additions */
+  $('#sw_calcium').val(Round(ws_calcium, 1));
+  $('#sw_magnesium').val(Round(ws_magnesium, 1));
+  $('#sw_sodium').val(Round(ws_sodium, 1));
+  $('#sw_sulfate').val(Round(ws_sulfate, 1));
+  $('#sw_chloride').val(Round(ws_chloride, 1));
+  $('#sw_bicarbonate').val(Round(Bicarbonate(ws_total_alkalinity, Source_pH), 1));
+  $('#sw_total_alkalinity').val(Round(ws_total_alkalinity, 1));
+  $('#sw_ph').val(dataRecord.sparge_ph);
+  $('#sw_hardness').val(Hardness(ws_calcium, ws_magnesium));
+  $('#sw_ra').val(ResidualAlkalinity(ws_total_alkalinity, ws_calcium, ws_magnesium));
+
+  AT = dataRecord.sparge_acid_type;
+  if (AT < 0 || AT >= AcidTypeData.length) {
+   AT = 0;
+   dataRecord.sparge_acid_type = 0;
+   $('#sparge_acid_type').val(AcidTypeData[0].nl);
+   dataRecord.sparge_acid_perc = AcidTypeData[0].AcidPrc;
+   $('#sparge_acid_perc').val(dataRecord.sparge_acid_perc);
+  }
+
+  /*
+   * Auto calculate the required acid
+   */
+  if (dataRecord.calc_acid) {
+   // Step 1: Compute the mole fractions of carbonic (f1) and carbonate(f3) at the source water pH
+   var r1 = Math.pow(10, Source_pH - 6.35);
+   var r2 = Math.pow(10, Source_pH - 10.33);
+   var d = 1 + r1 + r1 * r2;
+   var f1 = 1 / d;
+   var f3 = r1 * r2 / d;
+
+   //Step 2. Compute the mole fractions at pH = 4.3 (the pH which defines alkalinity)
+   var r143 = Math.pow(10, 4.3 - 6.35);
+   var r243 = Math.pow(10, 4.3 - 10.33);
+   var d43 = 1 + r143 + r143 * r243;
+   var f143 = 1 / d43;
+   var f343 = r143 * r243 / d43;
+
+   //Step 4. Solve
+   var Ct = ws_total_alkalinity / 50 / ((f143 - f1) + (f3 - f343));
+
+   //Step 5. Compute mole fractions at desired pH
+   var r1g = Math.pow(10, TargetpH - 6.35);
+   var r2g = Math.pow(10, TargetpH - 10.33);
+   var dg = 1 + r1g + r1g * r2g;
+   var f1g = 1 / dg;
+   var f3g = r1g * r2g / dg;
+
+   //Step 6. Use these to compute the milliequivalents acid required per liter (mEq/L)
+   var Acid = Ct * ((f1g - f1) + (f3 - f3g)) + Math.pow(10, -TargetpH) - Math.pow(10, -Source_pH);  //mEq/l
+   Acid += 0.01;   // Add acid that would be required for distilled water.
+
+   //Step 8. Get the acid data.
+   var fract = CalcFrac(TargetpH, AcidTypeData[AT].pK1, AcidTypeData[AT].pK2, AcidTypeData[AT].pK3);
+
+   //Step 9. Now divide the mEq required by the "fraction". This is the required number of moles of acid.
+   Acid /= fract;
+
+   //Step 10. Multiply by molecular weight of the acid
+   Acid *= AcidTypeData[AT].MolWt; //mg
+
+   //Step 11. Divide by Specific Gravity and Percentage to get the final ml.
+   var RealSG = Round(((AcidTypeData[AT].AcidSG - 1000) * (dataRecord.sparge_acid_perc / 100)) + 1000, 2);
+   Acid = Acid / RealSG;           //ml
+   Acid *= dataRecord.sparge_volume; //ml acid total at 100%
+   Acid /= AcidTypeData[AT].AcidPrc / 100;     //ml acid at supplied strength
+   Acid = Round(Acid, 2);
+   dataRecord.sparge_acid_amount = Acid / 1000;
+   $('#sparge_acid_amount').val(Acid);
+  }
+
+  // Finally calculate the estimate preboil pH
+  var ph = -Math.log10(((Math.pow(10, -dataRecord.wb_ph) * dataRecord.wg_amount) + (Math.pow(10, -dataRecord.sparge_ph) * dataRecord.sparge_volume)) /
+          (dataRecord.wg_amount + dataRecord.sparge_volume));
+  $('#preboil_ph').val(ph);
+ }
+
+ function calcFermentation() {
+  var primary_svg, secondary_svg, final_svg, ABV;
+  if (dataRecord.brew_fermenter_sg < 1.020)
+   return;
+  if ((dataRecord.primary_end_sg > 0.990) && (dataRecord.primary_end_sg < dataRecord.brew_fermenter_sg)) {
+   primary_svg = Round(calc_svg(dataRecord.brew_fermenter_sg, dataRecord.primary_end_sg), 1);
+   $('#primary_svg').val(primary_svg);
+   if ((dataRecord.secondary_end_sg > 0.990) && (dataRecord.secondary_end_sg < dataRecord.brew_fermenter_sg)) {
+    secondary_svg = Round(calc_svg(dataRecord.brew_fermenter_sg, dataRecord.secondary_end_sg), 1);
+    $('#secondary_svg').val(secondary_svg);
+    if ((dataRecord.fg > 0.990) && (dataRecord.fg < dataRecord.brew_fermenter_sg)) {
+     final_svg = Round(calc_svg(dataRecord.brew_fermenter_sg, dataRecord.fg), 1);
+     $('#final_svg').val(final_svg);
+     ABV = Round(abvol(dataRecord.brew_fermenter_sg, dataRecord.fg), 2);
+     $('#final_abv').val(ABV);
+    }
+   }
+  }
+ }
+
+ function ResCO2(T) {
+  var F = T * 1.8 + 32;
+  return Round(3.0378 - 0.050062 * F + 0.00026555 * F * F, 6);
+ }
+
+ function CarbCO2toS(CO2, T, SFactor) {
+  //var sugar = SFactor * (CO2 - ResCO2(CO2, T)) / 0.286;
+  var sugar = Round(SFactor * (CO2 - ResCO2(T)) * 4.014094, 6);
+  if (sugar < 0)
+   sugar = 0;
+  return Round(sugar, 3);
+ }
+
+ function GetPressure(CO2, T1, T2) {
+  var P, V = CO2 - ResCO2(T1);
+  V = CO2; // TODO: temp only total pressure, testing
+  if (V < 0)
+   return 0;
+  P = -1.09145427669121 + 0.00800006989646477 * T2 + 0.000260276315484684 * T2 * T2 + 0.0215142075945119 * T2 * V +
+      0.674996600795854 * V + -0.00471757220150754 * V * V;
+  if (P < 0)
+   P = 0;
+  P = Round(P * 1.01325, 2); // atm to bar
+  console.log("GetPressure(" + CO2 + ", " + T1 + ", " + T2 + ")  V:" + V + "  Bar: " + P + " ignored ResCO2: " + ResCO2(T1));
+  return P;
+ }
+
+ function CarbCO2ToPressure(CO2, T) {
+  return (CO2 - (-0.000005594056 * Math.pow(T, 4) + 0.000144357886 * Math.pow(T, 3) +
+          0.000362999168 * T * T - 0.064872987645 * T + 1.641145175049)) /
+         (0.00000498031 * Math.pow(T, 4) - 0.00024358267 * Math.pow(T, 3) + 0.00385867329 * T * T - 0.05671206825 * T + 1.53801423376);
+ }
+
+ function calcCarbonation() {
+
+  var TSec, ABV, bvol, balc, babv, mvol, malc, tvol, talc, i, row, SFactor, pvol, pabv, Pressure, kabv;
+
+  console.log('calcCarbonation()');
+
+  TSec = dataRecord.secondary_temp;
+  if (TSec < 1)
+   TSec = dataRecord.primary_end_temp;
+  if (TSec < 1)
+   TSec = 18;
+
+  if (dataRecord.fg == 0.000)
+   ABV = abvol(dataRecord.brew_fermenter_sg, parseFloat($('#est_fg').jqxNumberInput('decimal')));
+  else
+   ABV = abvol(dataRecord.brew_fermenter_sg, dataRecord.fg);
+
+  /* Calculate new volume and alcohol. */
+  bvol = dataRecord.package_volume - (ABV * dataRecord.package_volume) / 100;
+  balc = dataRecord.package_volume - bvol;
+  mvol = dataRecord.package_infuse_amount - (dataRecord.package_infuse_abv * dataRecord.package_infuse_amount) / 100;
+  malc = dataRecord.package_infuse_amount - mvol;
+  talc = balc + malc;
+  tvol = bvol + mvol;
+  ABV = Round(talc / (tvol + talc) * 100, 2);
+  dataRecord.package_abv = ABV;
+  $('#package_abv').val(ABV);
+
+  //console.log("calcCarbonation() TSec:"+TSec+"  ABV:"+ABV);
+  if (!(rows = $('#fermentableGrid').jqxGrid('getrows'))) {
+   return;
+  }
+
+  // Bottles
+  dataRecord.bottle_priming_amount = 0;
+  dataRecord.bottle_priming_total = 0;
+  for (i = 0; i < rows.length; i++) {
+   row = rows[i];
+   if (row.f_added == 4) {
+    SFactor = 1 / ((row.f_yield / 100) * (1 - row.f_moisture / 100));
+    dataRecord.bottle_priming_amount = CarbCO2toS(dataRecord.bottle_carbonation, TSec, SFactor);
+    dataRecord.bottle_priming_total = Round(dataRecord.bottle_amount * dataRecord.bottle_priming_amount, 2);
+    $('#fermentableGrid').jqxGrid('setcellvalue', i, 'f_amount', dataRecord.bottle_priming_total / 1000);
+   }
+  }
+  $('#bottle_priming_amount').val(Round(dataRecord.bottle_priming_amount, 1));
+  $('#bottle_priming_total').val(dataRecord.bottle_priming_total);
+  pabv = ABV + dataRecord.bottle_priming_amount * 0.47 / 7.907;
+  pvol = dataRecord.bottle_amount - (pabv * dataRecord.bottle_amount) / 100;
+  talc = dataRecord.bottle_amount - pvol;
+  tvol = pvol + dataRecord.bottle_priming_water;
+  babv = Round(talc / (tvol + talc) * 100, 2);
+  //console.log("bottle pabv:"+pabv+" pvol:"+pvol+" wvol:"+dataRecord.bottle_priming_water+" tvol:"+tvol+" talc:"+talc+" abv:"+babv);
+  $('#bottle_abv').val(babv);
+  $('#bottle_pressure').val(GetPressure(dataRecord.bottle_carbonation, TSec, dataRecord.bottle_carbonation_temp));
+
+  // Kegs
+  Pressure = CarbCO2ToPressure(dataRecord.keg_carbonation, dataRecord.keg_carbonation_temp);
+  if (Pressure < 0)
+   Pressure = 0;
+  dataRecord.keg_pressure = Pressure;
+  $('#keg_pressure').val(Round(Pressure, 1));
+
+  dataRecord.keg_priming_amount = 0;
+  dataRecord.keg_priming_total = 0;
+  if (!dataRecord.keg_forced_carb) {
+   for (i = 0; i < rows.length; i++) {
+    row = rows[i];
+    if (row.f_added == 5) {
+     SFactor = 1 / ((row.f_yield / 100) * (1 - row.f_moisture / 100));
+     dataRecord.keg_priming_amount = CarbCO2toS(dataRecord.keg_carbonation, TSec, SFactor);
+     dataRecord.keg_priming_total = Round(dataRecord.keg_amount * dataRecord.keg_priming_amount, 2);
+     $('#fermentableGrid').jqxGrid('setcellvalue', i, 'f_amount', dataRecord.keg_priming_total / 1000);
+    }
+   }
+   $('#keg_priming_amount').val(Round(dataRecord.keg_priming_amount, 1));
+   $('#keg_priming_total').val(dataRecord.keg_priming_total);
+   pabv = ABV + dataRecord.keg_priming_amount * 0.47 / 7.907;
+   pvol = dataRecord.keg_amount - (pabv * dataRecord.keg_amount) / 100;
+   talc = dataRecord.keg_amount - pvol;
+   tvol = pvol + dataRecord.keg_priming_water;
+   kabv = Round(talc / (tvol + talc) * 100, 2);
+   //console.log("kegs  pabv:"+pabv+" pvol:"+pvol+" wvol:"+dataRecord.keg_priming_water+" tvol:"+tvol+" talc:"+talc+" abv:"+kabv);
+   $('#keg_abv').val(kabv);
+  } else {
+   $('#keg_priming_amount').val(0);
+   $('#keg_priming_total').val(0);
+   $('#keg_abv').val(ABV);
+  }
+ }
+
+ function calcStage() {
+  /*
+   * Set stage and enable or disable parts of the screens.
+   */
+  $('#stage').val(StageData[dataRecord.stage].nl);
+
+  /*
+   * Enable or disable parts of the screens.
+   */
+  $('#jqxTabs').jqxTabs((dataRecord.stage < 1) ? 'disableAt':'enableAt', 8);   // Brewday tab
+  $('#jqxTabs').jqxTabs((dataRecord.stage > 2) ? 'enableAt':'disableAt', 9);   // Fermentation tab
+  $('#jqxTabs').jqxTabs((dataRecord.stage < 9) ? 'disableAt':'enableAt', 11); // Tasting tab
+ }
+
+
+ // initialize the input fields.
+ // Tab 1, Algemeen
+ $('#name').jqxTooltip({ content: 'De naam voor dit product.' });
+ $('#code').jqxTooltip({ content: 'Product code nummer.' });
+ $('#birth').jqxTooltip({ content: 'De ontwerp datum van dit product.' });
+ $('#stage').jqxTooltip({ content: 'De productie fase van dit product.' });
+ $('#divide_batch').jqxTooltip({ content: 'Het aantal extra gesplitste batches.' });
+ $('#divide_type').jqxTooltip({ content: 'Het splitsing moment in het productie proces.' });
+ $('#notes').jqxTooltip({ content: 'De uitgebreide opmerkingen over dit product.' });
+ $('#type').jqxTooltip({ content: 'Het brouw type van dit recept.' });
+ $('#efficiency').jqxTooltip({ content: 'Het rendement van maischen en koken.' });
+ $('#batch_size').jqxTooltip({ content: 'Het volume van het gekoelde wort na het koken.' });
+ $('#boil_time').jqxTooltip({ content: 'De kooktijd in minuten.' });
+ $('#boil_size').jqxTooltip({ content: 'Het volume van het wort voor het koken.' });
+ $('#st_guide').jqxTooltip({ content: 'De bierstijl gids voor dit recept.'});
+ $('#st_name').jqxTooltip({ content: 'De bierstijl naam voor dit recept.'});
+ $('#st_letter').jqxTooltip({ content: 'De bierstijl letter voor dit recept.'});
+ $('#st_letter').jqxInput({ theme: theme, width: 90, height: 23 });
+ $('#st_type').jqxTooltip({ content: 'Het bierstijl type.'});
+ $('#st_category').jqxTooltip({ content: 'De Amerikaanse bierstijl categorie.'});
+ $('#st_category_number').jqxTooltip({ content: 'De Amerikaanse bierstijl categorie sub nummer.'});
+ $('#est_og').jqxTooltip({ content: 'Het begin SG wat je wilt bereiken. De moutstort wordt automatisch herberekend.' });
+ $('#st_og_min').jqxTooltip({ content: 'Het minimum begin SG voor deze bierstijl.'});
+ $('#st_og_max').jqxTooltip({ content: 'Het maximum begin SG voor deze bierstijl.'});
+ $('#est_fg').jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
+ $('#st_fg_min').jqxTooltip({ content: 'Het minimum eind SG voor deze bierstijl.'});
+ $('#st_fg_max').jqxTooltip({ content: 'Het maximum eind SG voor deze bierstijl.'});
+ $('#est_abv').jqxTooltip({ content: 'Alcohol volume %. Dit wordt automatisch berekend.' });
+ $('#st_abv_min').jqxTooltip({ content: 'Het minimum alcohol volume % voor deze bierstijl.'});
+ $('#st_abv_max').jqxTooltip({ content: 'Het maximum alcohol volume % voor deze bierstijl.'});
+ $('#est_color').jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' });
+ $('#st_color_min').jqxTooltip({ content: 'De minimum kleur voor deze bierstijl.'});
+ $('#st_color_max').jqxTooltip({ content: 'De maximum kleur voor deze bierstijl.'});
+ $('#est_ibu').jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' });
+ $('#st_ibu_min').jqxTooltip({ content: 'De minimum bitterheid voor deze bierstijl.'});
+ $('#st_ibu_max').jqxTooltip({ content: 'De maximum bitterheid voor deze bierstijl.'});
+ $('#kcal').jqxTooltip({ content: 'Energie-inhoud in kcal/liter.' });
+ $('#est_carb').jqxTooltip({ content: 'Koolzuur volume. Dit wordt automatisch berekend.' });
+ $('#st_carb_min').jqxTooltip({ content: 'Het minimum koolzuur volume voor deze bierstijl.'});
+ $('#st_carb_max').jqxTooltip({ content: 'Het maximum koolzuur volume voor deze bierstijl.'});
+
+ $('#name').jqxInput({ theme: theme, width: 640, height: 23 });
+ $('#code, #stage').jqxInput({ theme: theme, width: 100, height: 23 });
+ $('#locked').jqxCheckBox({ theme: theme, width: 120, height: 23, disabled: true });
+ $('#birth,#divide_batch,#divide_type').jqxInput({ theme: theme, width: 120, height: 23 });
+ $('#notes').jqxInput({ theme: theme, width: 960, height: 100 });
+ $('#type').jqxInput({ theme: theme, width: 180, height: 23 });
+ $('#efficiency').jqxNumberInput(Show1dec);
+ $('#batch_size').jqxNumberInput(Show1dec);
+ $('#boil_time').jqxNumberInput(Show0dec);
+ $('#boil_size').jqxNumberInput(Show2dec);
+ $('#st_guide,#st_name,#st_type,#st_category').jqxInput({ theme: theme, width: 250, height: 23 });
+ $('#est_og').jqxNumberInput(Show3dec);
+ $('#est_fg').jqxNumberInput(Show3dec);
+ $('#st_og_min,#st_og_max,#st_fg_min,#st_fg_max').jqxNumberInput({ inputMode: 'simple', theme: theme, width: 50, height: 23, decimalDigits: 3, readOnly: true });
+ $('#est_ibu,#est_color').jqxNumberInput(Show0dec);
+ $('#color_method').jqxInput({ theme: theme, width: 180, height: 23 });
+ $('#st_color_min,#st_color_max,#st_category_number,#st_ibu_min,#st_ibu_max,#kcal').jqxNumberInput(Smal0dec);
+ $('#ibu_method').jqxInput({ theme: theme, width: 180, height: 23 });
+ $('#est_abv,#st_abv_min,#st_abv_max,#est_carb,#st_carb_min,#st_carb_max').jqxNumberInput(Smal1dec);
+
+ // Tab 2, Equipment
+ $('#eq_name').jqxTooltip({ content: 'De naam van deze brouw apparatuur.' });
+ $('#eq_boil_size').jqxTooltip({ content: 'Normaal kook volume in liters' });
+ $('#eq_batch_size').jqxTooltip({ content: 'Berekende batch grootte in liters aan het eind van de kook.' });
+ $('#eq_tun_volume').jqxTooltip({ content: 'Maisch ketel volume.' });
+ $('#eq_top_up_water').jqxTooltip({ content: 'Extra water in het gistvat.' });
+ $('#eq_trub_chiller_loss').jqxTooltip({ content: 'Standaard verlies bij het overbrengen naar het gistvat.' });
+ $('#eq_evap_rate').jqxTooltip({ content: 'Verdamping in liters per uur.' });
+ $('#eq_boil_time').jqxTooltip({ content: 'Normale kooktijd in minuten, 0 voor no-boil recepten.' });
+ $('#eq_top_up_kettle').jqxTooltip({ content: 'Extra water toevoegen tijdens de kook.' });
+ $('#eq_hop_utilization').jqxTooltip({ content: '100% voor kleine installaties, hoger voor grote brouwerijen.' });
+ $('#eq_notes').jqxTooltip({ content: 'Opmerkingen over deze apparatuur.' });
+ $('#eq_lauter_volume').jqxTooltip({ content: 'Filterkuip volume.' });
+ $('#eq_lauter_deadspace').jqxTooltip({ content: 'Filterkuip verlies in liters.' });
+ $('#eq_kettle_volume').jqxTooltip({ content: 'Kook ketel volume in liters.' });
+ $('#eq_mash_volume').jqxTooltip({ content: 'Maisch water voor de eerste stap.' });
+ $('#eq_mash_max').jqxTooltip({ content: 'De maximale moutstort in Kg.' });
+ $('#eq_efficiency').jqxTooltip({ content: 'Gemiddeld brouwzaal rendement.' });
+
+ $('#eq_name').jqxInput({ theme: theme, width: 250, height: 23 });
+ $('#eq_evap_rate').jqxNumberInput(Show2dec);
+ $('#eq_boil_time,#eq_hop_utilization').jqxNumberInput(Show0dec);
+ $('#eq_notes').jqxInput({ theme: theme, width: 960, height: 200 });
+ $('#eq_boil_size,#eq_batch_size,#eq_tun_volume,#eq_top_up_water,#eq_trub_chiller_loss,#eq_top_up_kettle').jqxNumberInput(Show1dec);
+ $('#eq_lauter_volume,#eq_lauter_deadspace,#eq_kettle_volume,#eq_mash_volume,#eq_mash_max,#eq_efficiency').jqxNumberInput(Show1dec);
+
+ // Tab 3, Fermentables
+ $('#est_color2').jqxTooltip({ content: 'De kleur in EBC. Dit wordt automatisch berekend.' });
+ $('#est_og2').jqxTooltip({ content: 'Het geschatte begin SG van dit product.' });
+ $('#mash_kg').jqxTooltip({ content: 'Het gewicht van alle mouten in de maisch.' });
+
+ $('#est_color2').jqxNumberInput(Show0dec);
+ $('#est_og2,#mash_kg').jqxNumberInput(Show3dec);
+
+ $('#perc_malts').jqxProgressBar({
+  width: 300, height: 23, theme: theme, showText: true, max: 120, animationDuration: 0,
+  colorRanges: [{ stop: 90, color: '#008C00' },{ stop: 100, color: '#EB7331' },{ stop: 120, color: '#FF0000' }],
+  renderText: function(text) { return (Math.round(parseInt(text) * 1.2)) + '%'; }
+ });
+ $('#perc_sugars').jqxProgressBar({
+  width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0,
+  colorRanges: [{ stop: 20, color: '#008C00' },{ stop: 50, color: '#FF0000' }],
+  renderText: function(text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; }
+ });
+ $('#perc_cara').jqxProgressBar({
+  width: 300, height: 23, theme: theme, showText: true, max: 50, animationDuration: 0,
+  colorRanges: [{ stop: 25, color: '#008C00' },{ stop: 50, color: '#FF0000' }],
+  renderText: function(text) { return (Math.round(parseInt(text) * 5) / 10) + '%'; }
+ });
+ $('#ferm_lintner').jqxProgressBar({
+  width: 300, height: 23, theme: theme, showText: true, max: 200, animationDuration: 0,
+  colorRanges: [{ stop: 30, color: '#FF0000' },{ stop: 40, color: '#EB7331' },{ stop: 200, color: '#008C00' }],
+  renderText: function(text) { return (parseInt(text) * 2) + ' lintner'; }
+ });
+
+ // Tab 4, Hops
+ $('#est_ibu2').jqxTooltip({ content: 'De bitterheid in IBU. Dit wordt automatisch berekend.' });
+ $('#est_ibu2').jqxNumberInput(Smal0dec);
+ $('#hop_flavour').jqxProgressBar({
+  width: 300, height: 23, theme: theme, showText: true, animationDuration: 0,
+  colorRanges: [
+   { stop: 20, color: '#004D00' },
+   { stop: 40, color: '#008C00' },
+   { stop: 60, color: '#00BF00' },
+   { stop: 80, color: '#00FF00' },
+   { stop: 100, color: '#80FF80' }
+  ],
+  renderText: function(text) {
+   var val = parseInt(text);
+   if (val < 20)
+    return 'Weinig';
+   else if (val < 40)
+    return 'Matig';
+   else if (val < 60)
+    return 'Redelijk';
+   else if (val < 80)
+    return 'Veel';
+   else
+    return 'Zeer veel';
+   }
+ });
+ $('#hop_aroma').jqxProgressBar({
+  width: 300, height: 23, theme: theme, showText: true, animationDuration: 0,
+  colorRanges: [
+   { stop: 20, color: '#004D00' },
+   { stop: 40, color: '#008C00' },
+   { stop: 60, color: '#00BF00' },
+   { stop: 80, color: '#00FF00' },
+   { stop: 100, color: '#80FF80' }
+  ],
+  renderText: function(text) {
+   var val = parseInt(text);
+   if (val < 20)
+    return 'Weinig';
+   else if (val < 40)
+    return 'Matig';
+   else if (val < 60)
+    return 'Redelijk';
+   else if (val < 80)
+    return 'Veel';
+   else
+    return 'Zeer veel';
+  }
+ });
+
+ // Tab 5, Miscs
+
+ // Tab 6, Yeasts
+ $('#est_fg2').jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
+ $('#est_abv2').jqxTooltip({ content: 'Verwacht alcohol volume %. Dit wordt automatisch berekend.' });
+ $('#yeast_grams').jqxTooltip({ content: 'De gewenste totale hoeveelheid droge gist voor dit bier.' });
+ $('#yeast_gr_hl').jqxTooltip({ content: 'De werkelijke hoeveelheid gist per hectoliter.' });
+ $('#yeast_cells').jqxTooltip({ content: 'Het aantal miljard beschikbare gistcellen zonder eventuele starter.' });
+ $('#need_cells').jqxTooltip({ content: 'Het aantal miljard nodige cellen is afhankelijk van het begin SG, biertype en volume.' });
+ $('#plato_cells').jqxTooltip({ content: 'De berekende pitchrate in miljard cellen per ml per graad Plato.' });
+ $('#yeast_prod_date').jqxTooltip({ content: 'Bij korrelgisten is meestal "best voor" datum op het zakje gedrukt.<br>Gebruik die datum maar dan twee jaar eerder als productie datum.<br>Bij White Labs is de productie datum vier maanden voor de "Best by" datum die geprint op het buisje.<br>Bij Wyeast is dit de "manufacture date" die op het pak geprint is.<br>Voor schuine buis, slurry, opkweek en gedroogd is dit de datum dat je de gist geoogst hebt.' });
+ $('#yeast_pitchrate').jqxTooltip({ content: 'De gewenste pitchrate in miljard cellen per ml per graad Plato voor de vergisting van dit bier.' });
+
+ $('#est_fg2,#plato_cells').jqxNumberInput(Show3dec);
+ $('#est_fg2').jqxNumberInput({ width: 70 });
+ $('#est_abv2').jqxNumberInput(Show2dec);
+ $('#est_abv2').jqxNumberInput({ width: 70, symbol: '%', symbolPosition: 'right' });
+ $('#yeast_grams').jqxNumberInput(Show1dec);
+ $('#yeast_gr_hl').jqxNumberInput(Show1dec);
+ $('#yeast_cells,#need_cells').jqxNumberInput(Show1dec);
+ $('#yeast_prod_date').jqxDateTimeInput(Dateopts);
+ $('#yeast_prod_date').jqxDateTimeInput({ disabled: true });
+ $('#yeast_pitchrate').jqxNumberInput(Show3dec);
+ for (i = 1; i < 5; i++) {
+  $('#prop' + i + '_volume').jqxTooltip({ content: 'Het volume van deze starter stap.' });
+  $('#prop' + i + '_irate').jqxTooltip({ content: 'Voor de beste gistgroei, houd de injectie factor tussen de 25 en 100 miljoen cellen per ml.' });
+  $('#prop' + i + '_ncells').jqxTooltip({ content: 'Het aantal miljard nieuwe gistcellen in deze stap.' });
+  $('#prop' + i + '_tcells').jqxTooltip({ content: 'Het totaal aantal miljard gistcellen na deze stap.' });
+  $('#prop' + i + '_growf').jqxTooltip({ content: 'De groeifactor, minstens 1. Ongeroerde starters komen meestal niet boven de 3.' });
+
+  $('#prop' + i + '_type').jqxInput({ theme: theme, width: 120, height: 23 });
+  $('#prop' + i + '_volume').jqxNumberInput(Show3dec);
+  $('#prop' + i + '_irate,#prop' + i + '_ncells,#prop' + i + '_tcells').jqxNumberInput(Show1dec);
+  $('#prop' + i + '_growf').jqxNumberInput(Show2dec);
+  $('#prop' + i + '_type,#prop' + i + '_volume,#prop' + i + '_irate,#prop' + i + '_ncells,#prop' + i + '_tcells,#prop' + i + '_growf').hide();
+ }
+ $('#starter_type').jqxInput({ theme: theme, width: 120, height: 23 });
+ $('#starter_sg').jqxTooltip({ content: 'Het ideale starter SG moet tussen de 1.030 en 1.040 zijn. Optimaal is 1.037.' });
+ $('#starter_sg').jqxNumberInput(Show3dec);
+ $('#starter_viability').jqxTooltip({ content: 'De gist conditie.' });
+ $('#starter_viability').jqxNumberInput(Show0dec);
+
+ // Tab 7, Mashing
+ $('#mash_name').jqxTooltip({ content: 'De omschrijving van dit maisch profiel.' });
+ $('#mash_name').jqxInput({ theme: theme, width: 320, height: 23 });
+ $('#est_mashvol').jqxTooltip({ content: 'Het totale volume van het maishwater en de mout in de maish pan.' });
+ $('#est_mashvol').jqxNumberInput(Show1dec);
+ $('#est_mashtime').jqxTooltip({ content: 'De totale tijdsduur van het maischen.' });
+ $('#est_mashtime').jqxInput({ theme: theme, width: 70, height: 23 });
+
+ // Tab 8, Water
+ $('#tgt_bu').jqxNumberInput(Show2wat);
+ $('#tgt_so4_cl,#got_so4_cl').jqxNumberInput(Show1wat);
+ $('#preboil_ph').jqxNumberInput(Show2wat);
+
+ // Water source 1
+ $('#w1_name').jqxInput({ theme: theme, width: 200, height: 23 });
+ $('#w1_button').jqxRadioButton({ theme: theme, width: 50, height: 23, disabled: true });
+ $('#w1_amount,#w1_calcium,#w1_magnesium,#w1_sodium,#w1_bicarbonate,#w1_total_alkalinity,#w1_chloride,#w1_sulfate').jqxNumberInput(Show1wat);
+ $('#w1_ph').jqxNumberInput(Show2wat);
+ $('#w1_hardness').jqxNumberInput(Show1wat);
+ $('#w1_ra').jqxNumberInput(Show1wat);
+ // Water source 2
+ $('#w2_name').jqxInput({ theme: theme, width: 200, height: 23 });
+ $('#w2_button').jqxRadioButton({ theme: theme, width: 50, height: 23, disabled: true });
+ $('#w2_amount').jqxNumberInput(Show1wat);
+ $('#w2_calcium,#w2_magnesium,#w2_sodium,#w2_bicarbonate,#w2_total_alkalinity,#w2_chloride,#w2_sulfate').jqxNumberInput(Show1wat);
+ $('#w2_ph').jqxNumberInput(Show2wat);
+ $('#w2_hardness').jqxNumberInput(Show1wat);
+ $('#w2_ra').jqxNumberInput(Show1wat);
+ // Water mixed
+ $('#wg_button').jqxRadioButton({ theme: theme, width: 50, height: 23, disabled: true });
+ $('#wg_amount,#wg_calcium,#wg_magnesium,#wg_sodium,#wg_bicarbonate,#wg_total_alkalinity,#wg_chloride,#wg_sulfate').jqxNumberInput(Show1wat);
+ $('#wg_ph').jqxNumberInput(Show2wat);
+ $('#wg_hardness').jqxNumberInput(Show1wat);
+ $('#wg_ra').jqxNumberInput(Show1wat);
+ // Water treated
+ $('#wb_calcium').jqxTooltip({ content: 'De ideale hoeveelheid Calcium is tussen 40 en 150.'});
+ $('#wb_calcium').jqxNumberInput(Show1wat);
+ $('#wb_magnesium').jqxTooltip({ content: 'De ideale hoeveelheid Magnesium is tussen 5 en 40.'});
+ $('#wb_magnesium').jqxNumberInput(Show1wat);
+ $('#wb_sodium').jqxTooltip({ content: 'De ideale hoeveelheid Natrium is lager dan 150.'});
+ $('#wb_sodium').jqxNumberInput(Show1wat);
+ $('#wb_chloride').jqxTooltip({ content: 'De ideale hoeveelheid Chloride is tussen 50 en 150. Samen met Sulfaat minder dan 500.'});
+ $('#wb_chloride').jqxNumberInput(Show1wat);
+ $('#wb_sulfate').jqxTooltip({ content: 'De ideale hoeveelheid Sulfaat is tussen 50 en 400. Samen met Chloride minder dan 500.'});
+ $('#wb_sulfate').jqxNumberInput(Show1wat);
+ $('#wb_bicarbonate').jqxTooltip({ content: '0 tot 50 lichte bieren, 50 tot 150 amber bieren, 150 tot 250 donkere bieren.'});
+ $('#wb_bicarbonate').jqxNumberInput(Show1wat);
+ $('#wb_ph').jqxNumberInput(Show2wat);
+ $('#wb_hardness').jqxNumberInput(Show1wat);
+ $('#wb_ra').jqxNumberInput(Show1wat);
+ // Sparge water
+ $('#sw_amount').jqxNumberInput(Show1wat);
+ $('#sw_calcium').jqxNumberInput(Show1wat);
+ $('#sw_magnesium').jqxNumberInput(Show1wat);
+ $('#sw_sodium').jqxNumberInput(Show1wat);
+ $('#sw_bicarbonate').jqxNumberInput(Show1wat);
+ $('#sw_total_alkalinity').jqxNumberInput(Show1wat);
+ $('#sw_chloride').jqxNumberInput(Show1wat);
+ $('#sw_sulfate').jqxNumberInput(Show1wat);
+ $('#sw_ph').jqxNumberInput(Show2wat);
+ $('#sw_hardness').jqxNumberInput(Show1wat);
+ $('#sw_ra').jqxNumberInput(Show1wat);
+
+ // Water agents
+ $('#wa_cacl2').jqxTooltip({ content: 'Voor het maken van een ander waterprofiel. Voegt calcium en chloride toe. Voor het verbeteren van zoetere bieren.' });
+ $('#wa_cacl2').jqxNumberInput(Show2wat);
+ $('#ss_cacl2').jqxNumberInput(Show2wat);
+
+ $('#wa_caso4').jqxTooltip({
+  content: 'Gips. Voor het maken van een ander waterprofiel. Voegt calcium en sulfaat toe. Voor het verbeteren van bittere bieren.'
+ });
+ $('#wa_caso4').jqxNumberInput(Show2wat);
+ $('#ss_caso4').jqxNumberInput(Show2wat);
+
+ $('#wa_mgso4').jqxTooltip({ content: 'Epsom zout. Voor het maken van een ander waterprofiel. Voegt magnesium en sulfaat toe. Gebruik spaarzaam!' });
+ $('#wa_mgso4').jqxNumberInput(Show2wat);
+ $('#ss_mgso4').jqxNumberInput(Show2wat);
+
+ $('#wa_nacl').jqxTooltip({
+  content: 'Keukenzout. Voor het maken van een ander waterprofiel. Voegt natrium en chloride toe. ' +
+  'Voor het accentueren van zoetheid. Bij hoge dosering wordt het bier ziltig.'
+ });
+ $('#wa_nacl').jqxNumberInput(Show2wat);
+ $('#ss_nacl').jqxNumberInput(Show2wat);
+
+ $('#wa_mgcl2').jqxTooltip({ content: 'Magnesiumchloride'});
+ $('#wa_mgcl2').jqxNumberInput(Show2wat);
+ $('#ss_mgcl2').jqxNumberInput(Show2wat);
+
+ $('#wa_nahco3').jqxTooltip({ content: 'Baksoda'});
+ $('#wa_caco3').jqxTooltip({ content: 'Kalk'});
+ $('#wa_nahco3,#wa_caco3').jqxNumberInput(Show2wat);
+
+ $('#mash_ph').jqxTooltip({ content: 'Maisch pH tussen 5.2 en 5.6. Gebruik 5.2 voor lichte en 5.5 voor donkere bieren.'});
+ $('#mash_ph').jqxNumberInput(Show2dec);
+
+ $('#calc_acid').jqxCheckBox({ theme: theme, width: 120, height: 23, disabled: true });
+
+ $('#wa_acid_name').jqxInput({ theme: theme, width: 130, height: 23 });
+ $('#wa_acid').jqxNumberInput(Show2dec);
+ $('#wa_acid').jqxNumberInput({ symbol: ' ml', symbolPosition: 'right' });
+ $('#wa_acid_perc').jqxNumberInput(Show0dec);
+ $('#wa_acid_perc').jqxNumberInput({ symbol: '%', symbolPosition: 'right' });
+
+ // Sparge water
+ $('#sparge_ph').jqxNumberInput(Show2dec);
+ $('#sparge_acid_amount').jqxNumberInput(Show2dec);
+ $('#sparge_acid_amount').jqxNumberInput({ symbol: ' ml', symbolPosition: 'right' });
+ $('#sparge_acid_type').jqxInput({ theme: theme, width: 130, height: 23 });
+ $('#sparge_acid_perc').jqxNumberInput(Show0dec);
+ $('#sparge_acid_perc').jqxNumberInput({ symbol: '%', symbolPosition: 'right' });
+
+ // Tab 9, Brewday
+ $('#brew_date_start').jqxTooltip({ content: 'Brouw datum en tijd. Voor planning laat de tijd op 00:00:00 staan.' });
+ $('#brew_date_end').jqxTooltip({ content: 'End datum en tijd van de brouw. Leeg laten als er nog niet gebrouwen is.' });
+ $('#brew_mash_ph').jqxTooltip({ content: 'De gemeten pH tijdens het maischen eventueel na correctie.' });
+ $('#est_mash_ph').jqxTooltip({ content: 'De gewenste pH tijdens het maischen.' });
+ $('#brew_preboil_ph').jqxTooltip({ content: 'De gemeten pH in de kookketel na het spoelen en voor de kook.' });
+ $('#brew_aboil_ph').jqxTooltip({ content: 'De gemeten pH na het koken.' });
+ $('#brew_mash_sg').jqxTooltip({ content: 'Het bereikte SG na het maischen.' });
+ $('#est_mash_sg').jqxTooltip({ content: 'Het berekende verwachte SG na het maischen.' });
+ $('#brew_preboil_sg').jqxTooltip({ content: 'Het gemeten SG in de kookketel na het spoelen en voor het koken.' });
+ $('#est_pre_sg').jqxTooltip({ content: 'Het berekende SG in de kookketel na het spoelen en voor het koken.' });
+ $('#brew_aboil_sg').jqxTooltip({ content: 'Het gemeten SG in de kookketel na het koken.' });
+ $('#est_og3').jqxTooltip({ content: 'Het gewenste SG in de kookketel na het koken zonder eventuele suikers die tijdens de vergisting toegevoegd worden.' });
+ $('#brew_mash_efficiency').jqxTooltip({ content: 'Het behaalde maisch rendement.' });
+ $('#brew_preboil_volume').jqxTooltip({ content: 'Het gemeten volume van het wort voor het koken.' });
+ $('#est_pre_vol').jqxTooltip({ content: 'Het berekende volume van het wort voor het koken.' });
+ $('#brew_aboil_volume').jqxTooltip({ content: 'Het gemeten volume van het wort na het koken.' });
+ $('#est_a_vol').jqxTooltip({ content: 'Het gewenste volume na het koken.' });
+ $('#brew_preboil_efficiency').jqxTooltip({ content: 'Het berekende rendement voor het koken.' });
+ $('#brew_aboil_efficiency').jqxTooltip({ content: 'Het bereikte rendement na het koken.' });
+ $('#brew_sparge_temperature').jqxTooltip({ content: 'De spoelwater temperatuur, in te stellen in de Water tab.' });
+ $('#brew_sparge_volume').jqxTooltip({ content: 'Het spoelwater voorraad volume, in te stellen in de Water tab.' });
+ $('#brew_date_start,#brew_date_end').jqxDateTimeInput(DateTimeopts);
+ $('#brew_date_start,#brew_date_end').jqxDateTimeInput({ disabled: true });
+ $('#est_mash_ph').jqxNumberInput(Show2wat);
+ $('#brew_mash_ph,#brew_preboil_ph,#brew_aboil_ph').jqxNumberInput(Show2dec);
+ $('#brew_mash_sg,#brew_preboil_sg,#brew_aboil_sg').jqxNumberInput(Show3dec);
+ $('#est_mash_sg,#est_pre_sg,#est_og3').jqxNumberInput(Show3wat);
+ $('#brew_mash_efficiency').jqxNumberInput(Show1dec);
+ $('#brew_preboil_volume,#brew_aboil_volume').jqxNumberInput(Show1dec);
+ $('#est_pre_vol,#est_a_vol').jqxNumberInput(Show1wat);
+ $('#brew_preboil_efficiency,#brew_aboil_efficiency,#brew_sparge_temperature,#brew_sparge_volume,#brew_sparge_est').jqxNumberInput(Show1dec);
+ $('#brew_cooling_to').jqxNumberInput(Show1dec);
+ $('#brew_sparge_ph').jqxNumberInput(Show2dec);
+ $('#brew_cooling_method').jqxInput({ theme: theme, width: 180, height: 23 });
+ $('#brew_cooling_time,#brew_whirlpool9,#brew_whirlpool7,#brew_whirlpool6,#brew_whirlpool2,#brew_aeration_time,#brew_aeration_speed').jqxNumberInput(Show0dec);
+ $('#brew_aeration_type').jqxInput({ theme: theme, width: 180, height: 23 });
+ $('#brew_fermenter_volume').jqxNumberInput(Show1dec);
+ $('#brew_fermenter_sg').jqxNumberInput(Show3dec);
+ $('#brew_fermenter_extrawater,#brew_fermenter_tcloss').jqxNumberInput(Show1dec);
+ $('#brew_fermenter_ibu,#brew_fermenter_color').jqxNumberInput(Show0dec);
+
+ // Tab 10, Fermentation
+ $('#brew_fermenter_sg2').jqxTooltip({ content: 'Het behaalde SG in het gistvat, overgenomen van de brouwdag.' });
+ $('#primary_start_temp').jqxTooltip({ content: 'De begintemperatuur van de hoofdvergisting.' });
+ $('#primary_max_temp').jqxTooltip({ content: 'De hoogst bereikte piek temperatuur tijdens de hoofgvergisting.' });
+ $('#primary_end_temp').jqxTooltip({ content: 'De eind temperatuur van de hoofdvergisting.' });
+ $('#primary_end_sg').jqxTooltip({ content: 'Het gemeten SG aan het eind van de hoofdvergisting.' });
+ $('#primary_svg').jqxTooltip({ content: 'De schijnbare vergisting graad behaald na de hoofdgisting.' });
+ $('#primary_end_date').jqxTooltip({ content: 'De eind datum van de hoofdvergisting en eventueel overhevelen.' });
+ $('#secondary_end_sg').jqxTooltip({ content: 'Het gemeten SG aan het eind van de navergisting.' });
+ $('#secondary_svg').jqxTooltip({ content: 'De schijnbare vergisting graad behaald na de nagisting.' });
+ $('#secondary_end_date').jqxTooltip({ content: 'De eind datum van de navergisting en het begin van het lageren.' });
+ $('#est_fg3').jqxTooltip({ content: 'Het verwachte eind SG. Dit wordt automatisch berekend.' });
+
+ $('#primary_end_sg,#secondary_end_sg').jqxNumberInput(Show3dec);
+ $('#primary_end_date,#secondary_end_date').jqxDateTimeInput(Dateopts);
+ $('#primary_end_date,#secondary_end_date').jqxDateTimeInput({ disabled: true });
+ $('#primary_start_temp,#primary_max_temp,#primary_end_temp,#secondary_temp,#tertiary_temp').jqxNumberInput(Show1dec);
+ $('#fg').jqxNumberInput(Show3dec);
+ $('#brew_fermenter_sg2,#est_fg3').jqxNumberInput(Show3dec);
+ $('#final_abv').jqxNumberInput(Show2dec);
+ $('#primary_svg,#secondary_svg,#final_svg').jqxNumberInput(Show1dec);
+ $('#FLog').jqxButton({ template: 'info', width: '150px', theme: theme });
+ $('#FLog').click(function() {
+  // Open log in a new tab.
+  window.open('log_fermentation.php?code=' + dataRecord.code + '&name=' + dataRecord.name);
+ });
+ $('#ILog').jqxButton({ template: 'info', width: '150px', theme: theme });
+ $('#ILog').click(function() {
+  // Open log in a new tab.
+  window.open('log_ispindel.php?code=' + dataRecord.code + '&name=' + dataRecord.name);
+ });
+
+ // Tab 11, Packaging
+ // TODO: high gravity packaging, extra water and recalc abv, color and ibu.
+ $('#package_date').jqxTooltip({ content: 'De verpakkings datum van dit bier.' });
+ $('#package_volume').jqxTooltip({ content: 'Het beschikbare volume om te bottelen of op fust te zetten.' });
+ $('#package_infuse_amount').jqxTooltip({ content: 'De hoeveelheid water of drank extra toe te voegen.' });
+ $('#package_infuse_abv').jqxTooltip({ content: 'De hoeveelheid alcohol in de drank, of 0.0 als het water is.' });
+ $('#package_infuse_notes').jqxTooltip({ content: 'Omschrijving van de extra toevoeging.' });
+ $('#package_abv').jqxTooltip({ content: 'De uiteindelijke hoeveelheid alcohol volume %.' });
+ $('#package_ph').jqxTooltip({ content: 'De gemeten pH vlak voor het verpakken.' });
+ $('#st_carb_min2').jqxTooltip({ content: 'Het minimum aanbevolen koolzuur volume voor deze bierstijl.'});
+ $('#st_carb_max2').jqxTooltip({ content: 'Het maximum aamnevolen koolzuur volume voor deze bierstijl.'});
+ $('#bottle_amount').jqxTooltip({ content: 'De totale hoeveelheid te bottelen bier.' });
+ $('#keg_amount').jqxTooltip({ content: 'De totale hoeveelheid op fust te zetten bier.' });
+ $('#bottle_carbonation').jqxTooltip({ content: 'Het gewenste CO2 volume in de flessen.' });
+ $('#keg_carbonation').jqxTooltip({ content: 'Het gewenste CO2 volume door de suiker in de fusten.' });
+ $('#bottle_priming_water,#keg_priming_water').jqxTooltip({ content: 'De hoeveelheid water om de suiker op te lossen.' });
+ $('#bottle_pressure').jqxTooltip({ content: 'De maximaal te verwachten druk tijdens het hergisten.' });
+ $('#package_date').jqxDateTimeInput(Dateopts);
+ $('#package_date').jqxDateTimeInput({ disabled: true });
+ $('#package_infuse_amount').jqxNumberInput(Show3dec);
+ $('#package_infuse_notes').jqxInput({ theme: theme, width: 640, height: 23 });
+ $('#package_abv').jqxNumberInput(Show2dec);
+ $('#package_ph').jqxNumberInput(Show2dec);
+ $('#st_carb_min2,#st_carb_max2').jqxNumberInput(Smal1dec);
+ $('#package_volume,#package_infuse_abv,#bottle_amount,#keg_amount').jqxNumberInput(Show1dec);
+ $('#bottle_carbonation,#keg_carbonation').jqxNumberInput(Show2dec);
+ $('#bottle_priming_sugar').jqxInput({ theme: theme, width: 200, height: 23 });
+ $('#keg_priming_sugar').jqxInput({ theme: theme, width: 200, height: 23 });
+ $('#bottle_priming_water,#keg_priming_water').jqxNumberInput(Show3dec);
+ $('#keg_forced_carb').jqxCheckBox({ theme: theme, width: 120, height: 23, disabled: true });
+ $('#bottle_priming_amount,#keg_priming_amount,#bottle_priming_total,#bottle_pressure,#keg_priming_total,#keg_pressure').jqxNumberInput(Show1dec);
+ $('#bottle_abv,#keg_abv').jqxNumberInput(Show2dec);
+ $('#bottle_carbonation_temp,#keg_carbonation_temp').jqxNumberInput(Show1dec);
+ $('#CLog').jqxButton({ template: 'info', width: '150px', theme: theme });
+ $('#CLog').click(function() {
+  // Open log in a new tab.
+  window.open('log_co2pressure.php?code=' + dataRecord.code + '&name=' + dataRecord.name);
+ });
+
+ // Tab 12, Tasting
+ $('#taste_date').jqxTooltip({ content: 'De proef datum van dit bier.' });
+ $('#taste_date').jqxDateTimeInput(Dateopts);
+ $('#taste_date').jqxDateTimeInput({ disabled: true });
+ $('#taste_rate').jqxTooltip({ content: 'Het cijfer voor dit bier van 1 tot 10.' });
+ $('#taste_rate').jqxNumberInput(Show1dec);
+ $('#taste_color').jqxTooltip({ content: 'De kleur van het bier.' });
+ $('#taste_transparency').jqxTooltip({ content: 'De helderheid van het bier.' });
+ $('#taste_head').jqxTooltip({ content: 'Het schuim op het bier.' });
+ $('#taste_color,#taste_transparency,#taste_head').jqxInput({ theme: theme, width: 320, height: 23 });
+ $('#taste_aroma').jqxTooltip({ content: 'Het aroma van het bier.' });
+ $('#taste_taste').jqxTooltip({ content: 'De smaak van het bier.' });
+ $('#taste_aftertaste').jqxTooltip({ content: 'De nasmaak van het bier.' });
+ $('#taste_mouthfeel').jqxTooltip({ content: 'Het mondgevoelvan het bier.' });
+ $('#taste_aroma,#taste_taste,#taste_aftertaste,#taste_mouthfeel').jqxInput({ theme: theme, width: 960, height: 23 });
+ $('#taste_notes').jqxTooltip({ content: 'Het oordeel en opmerkingen over dit bier.' });
+ $('#taste_notes').jqxInput({ theme: theme, width: 960, height: 100 });
+
+ $('#jqxTabs').jqxTabs({
+  theme: theme,
+  width: 1280,
+  height: 660,
+  autoHeight: false,
+  position: 'top'
+ });
+
+ // Buttons below
+ $('#Terug').jqxButton({ template: 'primary', width: '80px', theme: theme });
+ $('#Terug').bind('click', function() {
+  window.location.href = my_return;
+ });
+});
+
--- a/www/prod_edit.php	Sat Aug 06 22:02:42 2022 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,931 +0,0 @@
-<?php
-require_once($_SERVER['DOCUMENT_ROOT'].'/includes/global.inc.php');
-page_header('Brouw overzicht', 'prod_edit');
-?>
-
-   <div id='jqxTabs'>
-    <ul>
-     <li>Algemeen</li>
-     <li>Apparatuur</li>
-     <li>Vergistbaar</li>
-     <li>Hoppen</li>
-     <li>Diversen</li>
-     <li>Gist</li>
-     <li>Maischen</li>
-     <li>Water</li>
-     <li>Brouwdag</li>
-     <li>Vergisten</li>
-     <li>Verpakken</li>
-     <li>Proeven</li>
-    </ul>
-
-    <div> <!-- tab algemeen -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Brouw naam:</td>
-	<td align="left" colspan="3" style="vertical-align: top; padding: 3px;"><input id="name" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Afgesloten:</td>
-        <td align="left"><div id="locked"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Brouw code:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input id="code" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Start planning:</td>
-        <td align="left" style="vertical-align: top;"><input readonly="1" id="birth" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Brouw fase:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input id="stage" readonly /></td>
-       </tr>
-       <tr id='divide_row'>
-        <td style="vertical-align: top; float: right; padding: 3px;">Splits product:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input id="divide_type" readonly /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Gesplitst product:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input id="divide_batch" readonly /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Splits focus:</td>
-        <td align="left"><div id="d3"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Opmerkingen:</td>
-        <td colspan="5" style="padding: 3px;"><textarea id="notes"></textarea></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Brouw type:</td>
-        <td align="left" style="padding: 3px;"><input id="type" readonly /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Brouwzaal rendement:</td>
-	<td style="padding: 3px;"><div id="efficiency"></div></td>
-	<td style="vertical-align: top; float: right; padding: 3px;" id="ok_pmpt">Ingredienten aanwezig:</td>
-        <td align="left"><div id="ok_supplies"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Brouw volume:</td>
-        <td style="padding: 3px;"><div id="batch_size"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Kooktijd minuten:</td>
-        <td style="padding: 3px;"><div id="boil_time"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Kook volume:</td>
-        <td style="padding: 3px;"><div id="boil_size"></div></td>
-       </tr>
-       <tr>
-        <td colspan="6"><hr></td>
-       </tr>
-       <tr>
-        <td></td>
-        <th>Bierstijl gegevens</th>
-        <td colspan="4"></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Stijlgids:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_guide" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Bier stijl:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_name" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Bier groep:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_letter" /></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Stijl type:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1"  id="st_type" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Categorie:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_category" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Categorie nr:</td>
-        <td style="padding: 3px;"><div id="st_category_number"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Start SG:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_og"></div><div style="float: left; margin-left: 15px;" id="st_og_min"></div><div style="float: left; margin-left: 5px;" id="st_og_max"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind SG:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_fg"></div><div style="float: left; margin-left: 15px;" id="st_fg_min"></div><div style="float: left; margin-left: 5px;" id="st_fg_max"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Alcohol vol.%:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_abv"></div><div style="float: left; margin-left: 15px;" id="st_abv_min"></div><div style="float: left; margin-left: 5px;" id="st_abv_max"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Kleur EBC:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_color"></div><div style="float: left; margin-left: 15px;" id="st_color_min"></div><div style="float: left; margin-left: 5px;" id="st_color_max"></div><div id="bcolor" class='ebccolor'> </div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Kleur methode:</td>
-        <td style="padding: 3px;"><input id="color_method" readonly /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Koolzuur vol:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_carb"></div><div style="float: left; margin-left: 15px;" id="st_carb_min"></div><div style="float: left; margin-left: 5px;" id="st_carb_max"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheid IBU:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_ibu"></div><div style="float: left; margin-left: 15px;" id="st_ibu_min"></div><div style="float: left; margin-left: 5px;" id="st_ibu_max"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheid methode:</td>
-        <td style="padding: 3px;"><input id="ibu_method" readonly /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Energie-inhoud kcal/l:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="kcal"></div></td>
-       </tr>
-      </table>
-      <div style="float: right; margin-top: 20px; margin-bottom: 5px;">
-       <input style="margin-right: 600px;" type="button" id="Terug" value="Terug" />
-      </div>
-     </div>
-    </div>
-
-    <div> <!-- Apparatuur -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Installatie naam:</td>
-        <td colspan="3" align="left" style="vertical-align: top; padding: 3px;"><input id="eq_name" readonly /></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Opmerkingen:</td>
-        <td colspan="3" style="padding: 3px;"><textarea id="eq_notes" readonly></textarea></td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="2">Maischen</th>
-        <th style="text-align: center;" colspan="2">Koken</th>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right;">Maischkuip volume L:</td>
-        <td><div id="eq_tun_volume"></div></td>
-        <td style="vertical-align: top; float: right;">Kookketel volume L:</td>
-        <td><div id="eq_kettle_volume"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right;">Maischwater L:</td>
-        <td><div id="eq_mash_volume"></div></td>
-        <td style="vertical-align: top; float: right;">Kook volume L:</td>
-        <td><div id="eq_boil_size"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right;">Maximum moutstort Kg:</td>
-        <td><div id="eq_mash_max"></div></td>
-        <td style="vertical-align: top; float: right;">Verdamping per uur L:</td>
-        <td><div id="eq_evap_rate"></div></td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="2">Filteren</th>
-        <td style="vertical-align: top; float: right;">Kooktijd in minuten:</td>
-        <td><div id="eq_boil_time"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right;">Filter volume L:</td>
-        <td><div id="eq_lauter_volume"></div></td>
-        <td style="vertical-align: top; float: right;">Extra water bij koken L:</td>
-        <td><div id="eq_top_up_kettle"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right;">Filterkuip verlies L:</td>
-        <td><div id="eq_lauter_deadspace"></div></td>
-        <td style="vertical-align: top; float: right;">Hopfactor %:</td>
-        <td><div id="eq_hop_utilization"></div></td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="2">Koelen</th>
-        <td style="vertical-align: top; float: right;">Volume eind koken L:</td>
-        <td><div id="eq_batch_size"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right;">Trub verlies kookketel L:</td>
-        <td><div id="eq_trub_chiller_loss"></div></td>
-        <td style="vertical-align: top; float: right;">Brouwzaalrendement %:</td>
-        <td><div id="eq_efficiency"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right;">Extra water in gistvat:</td>
-	<td><div id="eq_top_up_water"></div></td>
-        <td colspan="2"></td>
-       </tr>
-      </table>
-     </div>
-    </div>
-
-    <div> <!-- tab vergistbaar -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Kleur EBC:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_color2"></div><div id="bcolor2" class='ebccolor'> </div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Percentage moutstort:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="perc_malts"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Begin SG:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_og2"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Percentage suiker:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="perc_sugars"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Maisch KG:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="mash_kg"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Percentage cara:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="perc_cara"></div></td>
-       </tr>
-       <tr>
-	<td colspan="2"> </td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Lintner totaal:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="ferm_lintner"></div></td>
-       </tr>
-       <tr>
-        <td align="center" colspan="4"><div id="fermentableGrid"></div></td>
-       </tr>
-      </table>
-     </div>
-    </div> <!-- tab vergistbaar -->
-
-    <div> <!-- tab hoppen -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheid IBU:</td>
-        <td style="padding: 3px;"><div id="est_ibu2"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Smaak bijdrage:</td>
-        <td style="padding: 3px;"><div id="hop_flavour"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Aroma bijdrage:</td>
-        <td style="padding: 3px;"><div id="hop_aroma"></div></td>
-       </tr>
-       <tr>
-        <td align="center" colspan="6"><div id="hopGrid"></div></td>
-       </tr>
-      </table>
-     </div>
-    </div> <!-- tab hoppen -->
-
-    <div> <!-- tab misc -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr><td>&nbsp;</td></tr>
-       <tr><td align="center"><div id="miscGrid"></div></td></tr>
-      </table>
-     </div>
-    </div> <!-- tab misc -->
-
-    <div> <!-- tab gisten -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Verwacht FG en ABV:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="est_fg2"></div><div style="float: left; margin-left: 10px;" id="est_abv2"></div></td>
-        <td align="center" colspan="5" rowspan="5">
-         <div id="propagator">
-          <table style="width: 100%;">
-           <caption>Giststarter stappen</caption>
-           <tr>
-            <td style="width: 40px; padding: 3px;">Stap</td>
-            <td align="left" style="vertical-align: top; padding: 3px;">Methode</td>
-            <td style="width: 120px; padding: 3px;">Volume</td>
-            <td style="width: 120px; padding: 3px;">Inj. factor</td>
-            <td style="width: 120px; padding: 3px;">Nieuwe cellen</td>
-            <td style="width: 120px; padding: 3px;">Totaal cellen</td>
-            <td style="width: 120px; padding: 3px;">Groei factor</td>
-           </tr>
-           <tr>
-            <td align="center">1</td>
-            <td><input id="prop1_type" readonly /><div id="r1_pmpt">Niet nodig</div></td>
-            <td><div id="prop1_volume"></div></td>
-            <td><div style="float: left;" id="prop1_irate"></div><div style="float: left;" id="r1_irate"></div></td>
-            <td><div id="prop1_ncells"></div></td>
-            <td><div style="float: left;" id="prop1_tcells"></div><div style="float: left;" id="r1_tcells"></div></td>
-            <td><div style="float: left;" id="prop1_growf"></div><div style="float: left;" id="r1_growf"></div></td>
-           </tr>
-           <tr>
-            <td align="center">2</td>
-            <td><input id="prop2_type" readonly /><div id="r2_pmpt">Niet nodig</div></td>
-            <td><div id="prop2_volume"></div></td>
-            <td><div style="float: left;" id="prop2_irate"></div><div style="float: left;" id="r2_irate"></div></td>
-            <td><div id="prop2_ncells"></div></td>
-            <td><div style="float: left;" id="prop2_tcells"></div><div style="float: left;" id="r2_tcells"></div></td>
-            <td><div style="float: left;" id="prop2_growf"></div><div style="float: left;" id="r2_growf"></div></td>
-           </tr>
-           <tr>
-            <td align="center">3</td>
-            <td><input id="prop3_type" readonly /><div id="r3_pmpt">Niet nodig</div></td>
-            <td><div id="prop3_volume"></div></td>
-            <td><div style="float: left;" id="prop3_irate"></div><div style="float: left;" id="r3_irate"></div></td>
-            <td><div id="prop3_ncells"></div></td>
-            <td><div style="float: left;" id="prop3_tcells"></div><div style="float: left;" id="r3_tcells"></div></td>
-            <td><div style="float: left;" id="prop3_growf"></div><div style="float: left;" id="r3_growf"></div></td>
-           </tr>
-           <tr>
-            <td align="center">4</td>
-            <td><input id="prop4_type" readonly /><div id="r4_pmpt">Niet nodig</div></td>
-            <td><div id="prop4_volume"></div></td>
-            <td><div style="float: left;" id="prop4_irate"></div><div style="float: left;" id="r4_irate"></div></td>
-            <td><div id="prop4_ncells"></div></td>
-            <td><div style="float: left;" id="prop4_tcells"></div><div style="float: left;" id="r4_tcells"></div></td>
-            <td><div style="float: left;" id="prop4_growf"></div><div style="float: left;" id="r4_growf"></div></td>
-           </tr>
-          </table>
-         </div>
-        </td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Gist productie datum:</td>
-        <td style="padding: 3px;"><div id="yeast_prod_date"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Gist conditie %:</td>
-        <td style="padding: 3px;"><div id="starter_viability"></div></td>
-       </tr>
-       <tr class="primary_dry">
-        <td style="vertical-align: top; float: right; padding: 3px;">Gist nodig gram:</td>
-        <td style="padding: 3px;"><div id="yeast_grams"></div></td>
-       </tr>
-       <tr class="primary_dry">
-        <td style="vertical-align: top; float: right; padding: 3px;">Ent hoeveelheid gr/hl:</td>
-        <td style="padding: 3px;"><div id="yeast_gr_hl"></div></td>
-       </tr>
-       <tr class="primary_liquid">
-        <td style="vertical-align: top; float: right; padding: 3px;">Gistcellen miljard:</td>
-        <td style="padding: 3px;"><div id="yeast_cells"></div></td>
-       </tr>
-       <tr class="primary_liquid">
-        <td style="vertical-align: top; float: right; padding: 3px;">Pitch rate:</td>
-        <td style="padding: 3px;"><div id="yeast_pitchrate"></div></td>
-       </tr>
-       <tr class="primary_liquid">
-        <td style="vertical-align: top; float: right; padding: 3px;">Cellen nodig miljard:</td>
-        <td style="padding: 3px;"><div id="need_cells"></div></td>
-       </tr>
-       <tr class="primary_liquid">
-        <td style="vertical-align: top; float: right; padding: 3px;">Pitch cellen/ml &deg;P:</td>
-        <td style="padding: 3px;"><div id="plato_cells"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Starter type:</td>
-	<td style="padding: 3px;"><input id="starter_type" readonly /></td>
- 	<td style="vertical-align: top; float: right; padding: 3px;">Starter SG:</td>
-	<td style="padding: 3px;"><div id="starter_sg"></div></td>
-        <td></td>
-       </tr>
-       <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
-       <tr><td align="center" colspan="7"><div id="yeastGrid"></div></td></tr>
-      </table>
-     </div>
-    </div> <!-- tab gisten -->
-
-    <div> <!-- tab maischen -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Maischchema:</td>
-	<td colspan="3" align="left" style="vertical-align: top; padding: 3px;"><input id="mash_name" readonly /></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Volume van de maisch L:</td>
-        <td style="padding: 3px;"><div id="est_mashvol"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Tijdsduur maischen:</td>
-        <td align="left" style="vertical-align: top; padding: 3px;"><input style="text-align:right" readonly="1" id="est_mashtime" /></td>
-       </tr>
-       <tr><td colspan="4">&nbsp;</td></tr>
-       <tr><td align="center" colspan="4" style="padding: 3px;"><div id="mashGrid"></div></td></tr>
-      </table>
-     </div>
-    </div> <!-- tab maischen -->
-
-    <div> <!-- tab water -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td align="center" colspan="9">
-         <div id='water_totals'>
-          <table style="width: 100%;">
-           <caption>Water overzicht</caption>
-           <tr>
-	    <td align="left" style="vertical-align: top; padding: 3px;">Water profiel</td>
-            <td style="width: 50px; padding: 3px;">Spoel</td>
-            <td style="width: 97px; padding: 3px;">Volume</td>
-            <td style="width: 77px; padding: 3px;">Ca</td>
-	    <td style="width: 77px; padding: 3px;">Mg</td>
-            <td style="width: 77px; padding: 3px;">HCO3</td>
-	    <td style="width: 77px; padding: 3px;">CaCO3</td>
-            <td style="width: 77px; padding: 3px;">Na</td>
-            <td style="width: 77px; padding: 3px;">Cl</td>
-            <td style="width: 77px; padding: 3px;">SO4</td>
-	    <td style="width: 77px; padding: 3px;">pH</td>
-            <td style="width: 77px; padding: 3px;">Hardheid</td>
-            <td style="width: 77px; padding: 3px;">RA</td>
-           </tr>
-           <tr>
-	    <td><input readonly="1" id="w1_name" /></td>
-            <td><div style='margin-left: 10px;' id='w1_button'></div></td>
-            <td><div id="w1_amount"></div></td>
-            <td><div id="w1_calcium"></div></td>
-	    <td><div id="w1_magnesium"></div></td>
-	    <td><div id="w1_bicarbonate"></div></td>
-            <td><div id="w1_total_alkalinity"></div></td>
-            <td><div id="w1_sodium"></div></td>
-            <td><div id="w1_chloride"></div></td>
-            <td><div id="w1_sulfate"></div></td>
-	    <td><div id="w1_ph"></div></td>
-            <td><div id="w1_hardness"></div></td>
-            <td><div id="w1_ra"></div></td>
-           </tr>
-           <tr>
-	    <td><input readonly="1" id="w2_name" /></td>
-            <td><div style='margin-left: 10px;' id='w2_button'></div></td>
-            <td><div id="w2_amount"></div></td>
-            <td><div id="w2_calcium"></div></td>
-	    <td><div id="w2_magnesium"></div></td>
-            <td><div id="w2_bicarbonate"></div></td>
-	    <td><div id="w2_total_alkalinity"></div></td>
-            <td><div id="w2_sodium"></div></td>
-            <td><div id="w2_chloride"></div></td>
-            <td><div id="w2_sulfate"></div></td>
-	    <td><div id="w2_ph"></div></td>
-            <td><div id="w2_hardness"></div></td>
-            <td><div id="w2_ra"></div></td>
-           </tr>
-           <tr>
-	    <td style="vertical-align: top; padding: 3px; float: left;">Gemengd water:</td>
-            <td><div style='margin-left: 10px;' id='wg_button'></div></td>
-            <td><div id="wg_amount"></div></td>
-            <td><div id="wg_calcium"></div></td>
-	    <td><div id="wg_magnesium"></div></td>
-            <td><div id="wg_bicarbonate"></div></td>
-	    <td><div id="wg_total_alkalinity"></div></td>
-            <td><div id="wg_sodium"></div></td>
-            <td><div id="wg_chloride"></div></td>
-            <td><div id="wg_sulfate"></div></td>
-	    <td><div id="wg_ph"></div></td>
-            <td><div id="wg_hardness"></div></td>
-            <td><div id="wg_ra"></div></td>
-           </tr>
-           <tr>
-	    <td style="vertical-align: top; padding: 3px; float: left;">Behandeld maisch water:</td>
-            <td></td>
-            <td><div></div></td>
-            <td><div id="wb_calcium"></div></td>
-	    <td><div id="wb_magnesium"></div></td>
-            <td><div id="wb_bicarbonate"></div></td>
-	    <td><div id="wb_total_alkalinity"></div></td>
-            <td><div id="wb_sodium"></div></td>
-            <td><div id="wb_chloride"></div></td>
-            <td><div id="wb_sulfate"></div></td>
-	    <td><div id="wb_ph"></div></td>
-            <td><div id="wb_hardness"></div></td>
-            <td><div id="wb_ra"></div></td>
-           </tr>
-           <tr>
-	    <td style="vertical-align: top; padding: 3px; float: left;">Resultaat:</td>
-            <td></td>
-            <td><div></div></td>
-            <td><div id="wr_calcium"></div></td>
-            <td><div id="wr_magnesium"></div></td>
-            <td><div id="wr_bicarbonate"></div></td>
-	    <td><div id="wr_total_alkalinity"></div></td>
-            <td><div id="wr_sodium"></div></td>
-            <td><div id="wr_chloride"></div></td>
-            <td><div id="wr_sulfate"></div></td>
-	    <td><div id="wr_ph"></div></td>
-            <td></td>
-            <td></td>
-	   </tr>
-           <tr>
-            <td style="vertical-align: top; padding: 3px; float: left;">Behandeld spoelwater:</td>
-            <td></td>
-            <td><div id="sw_amount"></div></td>
-            <td><div id="sw_calcium"></div></td>
-            <td><div id="sw_magnesium"></div></td>
-            <td><div id="sw_bicarbonate"></div></td>
-            <td><div id="sw_total_alkalinity"></div></td>
-            <td><div id="sw_sodium"></div></td>
-            <td><div id="sw_chloride"></div></td>
-            <td><div id="sw_sulfate"></div></td>
-            <td><div id="sw_ph"></div></td>
-            <td><div id="sw_hardness"></div></td>
-            <td><div id="sw_ra"></div></td>
-           </tr>
-          </table>
-         </div>
-        </td>
-       </tr>
-       <tr>
-	<th style="text-align: center;" colspan="3">Brouwzouten</th>
-	<th colspan="3"></th>
-        <th style="text-align: center;" colspan="3">Spoelwater</th>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">CaCl2 gr:</td>
-	<td style="padding: 3px;"><div id="wa_cacl2"></div></td>
-        <td style="padding: 3px;"><div id="ss_cacl2"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheidsindex:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="tgt_bu"></div></td>
-        <td style="padding: 3px;"><div style="float: left;" id="wr_bu"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Auto bereken:</td>
-        <td style="padding: 3px;"><div id="calc_acid"></div></td>
-        <td></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">CaSO4 gr:</td>
-	<td style="padding: 3px;"><div id="wa_caso4"></div></td>
-        <td style="padding: 3px;"><div id="ss_caso4"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Richtgetal SO4:Cl:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="tgt_so4_cl"></div></td>
-        <td style="padding: 3px;"><div style="float: left;" id="wrt_so4_cl"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;"><div class='c_mashph'>Gewenst maish pH:</div></td>
-        <td style="padding: 3px;"><div id="mash_ph" class='c_mashph'></div></td>
-        <td></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">MgSO4 gr:</td>
-	<td style="padding: 3px;"><div id="wa_mgso4"></div></td>
-        <td style="padding: 3px;"><div id="ss_mgso4"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Huidig SO4:Cl:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="got_so4_cl"></div></td>
-        <td style="padding: 3px;"><div style="float: left;" id="wr_so4_cl"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Aanzuren met:</td>
-        <td style="padding: 3px;"><input readonly="1" id="wa_acid_name" /></td>
-        <td style="padding: 3px;"><div style="float: left;" id="wa_acid_perc"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">NaCl gr:</td>
-	<td style="padding: 3px;"><div id="wa_nacl"></div></td>
-        <td style="padding: 3px;"><div id="ss_nacl"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Voor koken pH:</td>
-        <td style="padding: 3px;"><div id="preboil_ph"></div></td>
-        <td></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Zuur hoeveelheid:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="wa_acid"></div></td>
-        <td></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">MgCl2 gr:</td>
-	<td style="padding: 3px;"><div id="wa_mgcl2"></div></td>
-        <td style="padding: 3px;"><div id="ss_mgcl2"></div></td>
-        <td colspan="3"></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Gewenst spoel pH:</td>
-        <td style="padding: 3px;"><div id="sparge_ph"></div></td>
-        <td></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">NaHCO3 gr:</td>
-	<td style="padding: 3px;"><div id="wa_nahco3"></div></td>
-        <td colspan="4"></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Aanzuren met:</td>
-        <td style="padding: 3px;"><input readonly="1" id="sparge_acid_type" /></td>
-        <td style="padding: 3px;"><div id="sparge_acid_perc"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">CaCO3 gr:</td>
-	<td style="padding: 3px;"><div id="wa_caco3"></div></td>
-        <td colspan="4"></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Zuur hoeveelheid:</td>
-        <td style="padding: 3px;"><div id="sparge_acid_amount"></div></td>
-        <td></td>
-       </tr>
-      </table>
-     </div>
-    </div> <!-- tab water -->
-
-    <div style="overflow: hidden;"> <!-- Brewday -->
-     <table style="width: 100%;">
-      <tr>
-       <td style="vertical-align: top; float: right; padding: 3px;">Brouwdag start:</td>
-       <td align="left" colspan="2" style="vertical-align: top;"><div id="brew_date_start"></div></td>
-       <td style="vertical-align: top; float: right; padding: 3px;">Brouwdag eind:</td>
-       <td align="left" colspan="2" style="vertical-align: top;"><div id="brew_date_end"></div></td>
-      </tr>
-      <tr>
-       <td colspan="6"> </td>
-      </tr>
-      <tr>
-       <th style="text-align: center;" colspan="2">Maischen</th>
-       <th style="text-align: center;" colspan="4"><div id="brew_pmpt_koken">Koken</div></th>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Maisch pH:</td>
-       <td><div style="float: left;" id="brew_mash_ph"></div><div style="float: left; margin-left: 10px;" id="est_mash_ph"></div></td>
-       <td style="vertical-align: top; float: right;">Voor koken pH:</td>
-       <td><div id="brew_preboil_ph"></div></td>
-       <td style="vertical-align: top; float: right;">Na koken pH:</td>
-       <td><div id="brew_aboil_ph"></div></td>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Maisch SG:</td>
-       <td><div style="float: left;" id="brew_mash_sg"></div><div style="float: left; margin-left: 10px;" id="est_mash_sg"></div></td>
-       <td style="vertical-align: top; float: right;">Voor koken SG:</td>
-       <td><div style="float: left;" id="brew_preboil_sg"></div><div style="float: left; margin-left: 10px;" id="est_pre_sg"></div></td>
-       <td style="vertical-align: top; float: right;">Na koken SG:</td>
-       <td><div style="float: left;" id="brew_aboil_sg"></div><div style="float: left; margin-left: 10px;" id="est_og3"></div></td>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Maisch rendement %:</td>
-       <td><div id="brew_mash_efficiency"></div></td>
-       <td style="vertical-align: top; float: right;">Voor koken vol@100&deg;C:</td>
-       <td><div style="float: left;" id="brew_preboil_volume"></div><div style="float: left; margin-left: 10px;" id="est_pre_vol"></div></td>
-       <td style="vertical-align: top; float: right;">Na koken vol@100&deg;C:</td>
-       <td><div style="float: left;" id="brew_aboil_volume"></div><div style="float: left; margin-left: 10px;" id="est_a_vol"></div></td>
-      </tr>
-      <tr>
-       <td colspan="2"> </td>
-       <td style="vertical-align: top; float: right;">Voor koken rendement %:</td>
-       <td><div id="brew_preboil_efficiency"></div></td>
-       <td style="vertical-align: top; float: right;">Na koken rendement %:</td>
-       <td><div id="brew_aboil_efficiency"></div></td>
-      </tr>
-      <tr>
-       <td colspan="6">&nbsp;</td>
-      </tr>
-      <tr>
-       <th style="text-align: center;" colspan="2">Spoelen en filteren</th>
-       <th style="text-align: center;" colspan="4">Koelen en whirlpoolen</th>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Spoelwater &deg;C:</td>
-       <td><div id="brew_sparge_temperature"></div></td>
-       <td style="vertical-align: top; float: right;">Whirlpool 85..100&deg;C min:</td>
-       <td><div id="brew_whirlpool9"></div></td>
-       <td style="vertical-align: top; float: right;">Koelen tot &deg;C:</td>
-       <td><div id="brew_cooling_to"></div></td>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Spoelwater voorraad L:</td>
-       <td><div id="brew_sparge_volume"></div></td>
-       <td style="vertical-align: top; float: right;">Whirlpool 72..79&deg;C min:</td>
-       <td><div id="brew_whirlpool7"></div></td>
-       <td style="vertical-align: top; float: right;">Koelen met:</td>
-       <td><input readonly="1" id="brew_cooling_method" /></td>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Spoelwater nodig L:</td>
-       <td><div id="brew_sparge_est"></div></td>
-       <td style="vertical-align: top; float: right;">Whirlpool 60..66&deg;C min:</td>
-       <td><div id="brew_whirlpool6"></div></td>
-       <td style="vertical-align: top; float: right;">Koelen minuten:</td>
-       <td><div id="brew_cooling_time"></div></td>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Spoelwater pH:</td>
-       <td><div id="brew_sparge_ph"></div></td>
-       <td style="vertical-align: top; float: right;">Whirlpool koud min:</td>
-       <td><div id="brew_whirlpool2"></div></td>
-       <td colspan="2"> </td>
-      </tr>
-      <tr>
-       <td colspan="6">&nbsp;</td>
-      </tr>
-      <tr>
-       <th style="text-align: center;" colspan="2">Beluchten</th>
-       <th style="text-align: center;" colspan="4">Naar gistvat</th>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Beluchten met:</td>
-       <td><input readonly="1" id="brew_aeration_type" /></td>
-       <td style="vertical-align: top; float: right;">Koeler en trub verlies L:</td>
-       <td><div id="brew_fermenter_tcloss"></div></td>
-       <td style="vertical-align: top; float: right;">SG in gistvat:</td>
-       <td><div id="brew_fermenter_sg"></div></td>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Beluchten tijd min:</td>
-       <td><div id="brew_aeration_time"></div></td>
-       <td style="vertical-align: top; float: right;">Extra water in gistvat L:</td>
-       <td><div id="brew_fermenter_extrawater"></div></td>
-       <td style="vertical-align: top; float: right;">Kleur in gistvat EBC:</td>
-       <td><div style="float: left;" id="brew_fermenter_color"></div><div style="float: left; margin-left: 10px;" id="bcolorf" class='ebccolor'> </div></td>
-      </tr>
-      <tr>
-       <td style="vertical-align: top; float: right;">Beluchten snelheid:</td>
-       <td><div id="brew_aeration_speed"></div></td>
-       <td style="vertical-align: top; float: right;">Volume naar gistvat L:</td>
-       <td><div id="brew_fermenter_volume"></div></td>
-       <td style="vertical-align: top; float: right;">Bitterheid in gistvat IBU:</td>
-       <td><div style="float: left;" id="brew_fermenter_ibu"></div></td>
-      </tr>
-     </table>
-    </div> <!-- Brewday -->
-
-    <div> <!-- Vergisten -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-	<td style="width: 30%;"> </td>
-        <td style="width: 20%;"> </td>
-        <td style="width: 30%;"> </td>
-        <td style="width: 20%;"> </td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="4">Hoofdvergisting</th>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Begin vergisting SG:</td>
-	<td align="left" colspan="3" style="vertical-align: top;"><div id="brew_fermenter_sg2"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Start temperatuur hoofdvergisting &deg;C:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_start_temp"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Piek temperatuur hoofdvergisting &deg;C:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_max_temp"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind temperatuur hoofdvergisting &deg;C:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_temp"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind hoofdvergisting SG:</td>
-	<td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_sg"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind hoofdvergisting/overhevelen:</td>
-	<td align="left" style="vertical-align: top;"><div id="primary_end_date"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad:</td>
-        <td align="left" style="vertical-align: top;"><div id="primary_svg"></div></td>
-       </tr>
-       <tr>
-        <td colspan="4"><hr></td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="4">Nagisting</th>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Temperatuur nagisting &deg;C:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="secondary_temp"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind nagisting SG:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="secondary_end_sg"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Eind nagisting/start lageren:</td>
-        <td align="left" style="vertical-align: top;"><div id="secondary_end_date"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad %:</td>
-        <td align="left" style="vertical-align: top;"><div id="secondary_svg"></div></td>
-       </tr>
-       <tr>
-        <td colspan="4"><hr></td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="4">Lageren</th>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Temperatuur lageren &deg;C:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="tertiary_temp"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Het verwachte eind SG:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="est_fg3"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Het behaalde eind SG:</td>
-	<td align="left" colspan="3" style="vertical-align: top;"><div id="fg"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Alcoholgehalte voor hergisting vol.%:</td>
-        <td align="left" style="vertical-align: top;"><div id="final_abv"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad %:</td>
-        <td align="left" style="vertical-align: top;"><div id="final_svg"></div></td>
-       </tr>
-      </table>
-      <div style="float: right; margin-top: 55px; margin-bottom: 5px;">
-       <input style="margin-right: 100px;" type="button" id="FLog"  value="Klimaatkast log" />
-       <input style="margin-right: 475px;" type="button" id="ILog" value="Vergisting log" />
-      </div>
-     </div>
-    </div> <!-- Vergisten -->
-
-    <div> <!-- Verpakken -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Datum:</td>
-	<td align="left" style="vertical-align: top;"><div id="package_date"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Aanbevolen volume CO2:</td>
-        <td style="padding: 3px;"><div style="float: left;" id="st_carb_min2"></div><div style="float: left; margin-left: 5px;" id="st_carb_max2"></div></td>
-       </tr>
-       <tr>
-        <td colspan="4"><hr></td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="4">Verdunnen of infusie</th>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Volume na vergisting L:</td>
-        <td align="left" colspan="3" style="vertical-align: top;"><div id="package_volume"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Toevoeging Liter:</td>
-        <td align="left" style="vertical-align: top;"><div id="package_infuse_amount"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Toevoeging ABV %:</td>
-        <td align="left" style="vertical-align: top;"><div id="package_infuse_abv"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Toevoeging omschrijving:</td>
-        <td align="left" colspan="3" style="vertical-align: top; padding: 3px;"><input id="package_infuse_notes" /></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Alcohol volume %:</td>
-        <td align="left" style="vertical-align: top;"><div id="package_abv"></div></td>
-        <td style="vertical-align: top; float: right;">Bij verpakken pH:</td>
-        <td align="left" style="vertical-align: top;"><div id="package_ph"></div></td>
-       </tr>
-       <tr>
-        <td colspan="4"><hr></td>
-       </tr>
-       <tr>
-        <th style="text-align: center;" colspan="2">Flessen</th>
-        <th style="text-align: center;" colspan="2">Fusten</th>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Hoeveelheid Liter:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_amount"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Hoeveelheid Liter:</td>
-	<td align="left" style="vertical-align: top;"><div id="keg_amount"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Gewenst volume CO2:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_carbonation"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Gewenst volume CO2:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_carbonation"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Suiker:</td>
-        <td align="left" style="vertical-align: top;"><input readonly="1" id="bottle_priming_sugar" /></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Suiker:</td>
-        <td align="left" style="vertical-align: top;"><input readonly="1" id="keg_priming_sugar" /></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Toevoegen suiker g/L:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_priming_amount"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Toevoegen suiker g/L:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_priming_amount"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Suiker totaal gram:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_priming_total"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Suiker totaal gram:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_priming_total"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Suikeroplossing water L:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_priming_water"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Suikeroplossing water L:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_priming_water"></div></td>
-       </tr>
-       <tr>
-        <td colspan="2"></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Op druk brengen met CO2:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_forced_carb"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Verwachte flesdruk in bar:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_pressure"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Druk op fust bar:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_pressure"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Alcoholgehalte flessen vol.%:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_abv"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Alcoholgehalte fusten vol.%:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_abv"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Hergisting temperatuur:</td>
-        <td align="left" style="vertical-align: top;"><div id="bottle_carbonation_temp"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Keg temperatuur:</td>
-        <td align="left" style="vertical-align: top;"><div id="keg_carbonation_temp"></div></td>
-       </tr>
-      </table>
-      <div style="float: right; margin-top: 20px; margin-bottom: 5px;">
-       <input style="margin-right: 575px;" type="button" id="CLog" value="Hergisting log" />
-      </div>
-     </div>
-    </div> <!-- Verpakken -->
-
-    <div> <!-- Proeven -->
-     <div style="overflow: hidden;">
-      <table style="width: 100%;">
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Datum:</td>
-	<td align="left" style="vertical-align: top;"><div id="taste_date"></div></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Cijfer:</td>
-        <td align="left" style="vertical-align: top;"><div id="taste_rate"></div></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Kleur:</td>
-	<td style="padding: 3px;"><textarea id="taste_color" readonly></textarea></td>
-        <td style="vertical-align: top; float: right; padding: 3px;">Helderheid:</td>
-        <td style="padding: 3px;"><textarea id="taste_transparency" readonly></textarea></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Schuim:</td>
-        <td colspan="3" style="padding: 3px;"><textarea id="taste_head" readonly></textarea></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Aroma:</td>
-        <td colspan="3" style="padding: 3px;"><textarea id="taste_aroma" readonly></textarea></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Smaak:</td>
-        <td colspan="3" style="padding: 3px;"><textarea id="taste_taste" readonly></textarea></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Nasmaak:</td>
-        <td colspan="3" style="padding: 3px;"><textarea id="taste_aftertaste" readonly></textarea></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Mondgevoel:</td>
-        <td colspan="3" style="padding: 3px;"><textarea id="taste_mouthfeel" readonly></textarea></td>
-       </tr>
-       <tr>
-        <td style="vertical-align: top; float: right; padding: 3px;">Oordeel:</td>
-        <td colspan="3" style="padding: 3px;"><textarea id="taste_notes" readonly></textarea></td>
-       </tr>
-      </table>
-     </div>
-    </div> <!-- Proeven -->
-
-   </div> <!-- Tabs -->
-
-<?php
-page_footer();
-?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/www/prod_view.php	Sat Aug 06 22:10:28 2022 +0200
@@ -0,0 +1,931 @@
+<?php
+require_once($_SERVER['DOCUMENT_ROOT'].'/includes/global.inc.php');
+page_header('Brouw overzicht', 'prod_view');
+?>
+
+   <div id='jqxTabs'>
+    <ul>
+     <li>Algemeen</li>
+     <li>Apparatuur</li>
+     <li>Vergistbaar</li>
+     <li>Hoppen</li>
+     <li>Diversen</li>
+     <li>Gist</li>
+     <li>Maischen</li>
+     <li>Water</li>
+     <li>Brouwdag</li>
+     <li>Vergisten</li>
+     <li>Verpakken</li>
+     <li>Proeven</li>
+    </ul>
+
+    <div> <!-- tab algemeen -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Brouw naam:</td>
+	<td align="left" colspan="3" style="vertical-align: top; padding: 3px;"><input id="name" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Afgesloten:</td>
+        <td align="left"><div id="locked"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Brouw code:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input id="code" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Start planning:</td>
+        <td align="left" style="vertical-align: top;"><input readonly="1" id="birth" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Brouw fase:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input id="stage" readonly /></td>
+       </tr>
+       <tr id='divide_row'>
+        <td style="vertical-align: top; float: right; padding: 3px;">Splits product:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input id="divide_type" readonly /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Gesplitst product:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input id="divide_batch" readonly /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Splits focus:</td>
+        <td align="left"><div id="d3"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Opmerkingen:</td>
+        <td colspan="5" style="padding: 3px;"><textarea id="notes"></textarea></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Brouw type:</td>
+        <td align="left" style="padding: 3px;"><input id="type" readonly /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Brouwzaal rendement:</td>
+	<td style="padding: 3px;"><div id="efficiency"></div></td>
+	<td style="vertical-align: top; float: right; padding: 3px;" id="ok_pmpt">Ingredienten aanwezig:</td>
+        <td align="left"><div id="ok_supplies"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Brouw volume:</td>
+        <td style="padding: 3px;"><div id="batch_size"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Kooktijd minuten:</td>
+        <td style="padding: 3px;"><div id="boil_time"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Kook volume:</td>
+        <td style="padding: 3px;"><div id="boil_size"></div></td>
+       </tr>
+       <tr>
+        <td colspan="6"><hr></td>
+       </tr>
+       <tr>
+        <td></td>
+        <th>Bierstijl gegevens</th>
+        <td colspan="4"></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Stijlgids:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_guide" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Bier stijl:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_name" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Bier groep:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_letter" /></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Stijl type:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1"  id="st_type" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Categorie:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input readonly="1" id="st_category" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Categorie nr:</td>
+        <td style="padding: 3px;"><div id="st_category_number"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Start SG:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_og"></div><div style="float: left; margin-left: 15px;" id="st_og_min"></div><div style="float: left; margin-left: 5px;" id="st_og_max"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind SG:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_fg"></div><div style="float: left; margin-left: 15px;" id="st_fg_min"></div><div style="float: left; margin-left: 5px;" id="st_fg_max"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Alcohol vol.%:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_abv"></div><div style="float: left; margin-left: 15px;" id="st_abv_min"></div><div style="float: left; margin-left: 5px;" id="st_abv_max"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Kleur EBC:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_color"></div><div style="float: left; margin-left: 15px;" id="st_color_min"></div><div style="float: left; margin-left: 5px;" id="st_color_max"></div><div id="bcolor" class='ebccolor'> </div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Kleur methode:</td>
+        <td style="padding: 3px;"><input id="color_method" readonly /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Koolzuur vol:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_carb"></div><div style="float: left; margin-left: 15px;" id="st_carb_min"></div><div style="float: left; margin-left: 5px;" id="st_carb_max"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheid IBU:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_ibu"></div><div style="float: left; margin-left: 15px;" id="st_ibu_min"></div><div style="float: left; margin-left: 5px;" id="st_ibu_max"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheid methode:</td>
+        <td style="padding: 3px;"><input id="ibu_method" readonly /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Energie-inhoud kcal/l:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="kcal"></div></td>
+       </tr>
+      </table>
+      <div style="float: right; margin-top: 20px; margin-bottom: 5px;">
+       <input style="margin-right: 600px;" type="button" id="Terug" value="Terug" />
+      </div>
+     </div>
+    </div>
+
+    <div> <!-- Apparatuur -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Installatie naam:</td>
+        <td colspan="3" align="left" style="vertical-align: top; padding: 3px;"><input id="eq_name" readonly /></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Opmerkingen:</td>
+        <td colspan="3" style="padding: 3px;"><textarea id="eq_notes" readonly></textarea></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="2">Maischen</th>
+        <th style="text-align: center;" colspan="2">Koken</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right;">Maischkuip volume L:</td>
+        <td><div id="eq_tun_volume"></div></td>
+        <td style="vertical-align: top; float: right;">Kookketel volume L:</td>
+        <td><div id="eq_kettle_volume"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right;">Maischwater L:</td>
+        <td><div id="eq_mash_volume"></div></td>
+        <td style="vertical-align: top; float: right;">Kook volume L:</td>
+        <td><div id="eq_boil_size"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right;">Maximum moutstort Kg:</td>
+        <td><div id="eq_mash_max"></div></td>
+        <td style="vertical-align: top; float: right;">Verdamping per uur L:</td>
+        <td><div id="eq_evap_rate"></div></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="2">Filteren</th>
+        <td style="vertical-align: top; float: right;">Kooktijd in minuten:</td>
+        <td><div id="eq_boil_time"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right;">Filter volume L:</td>
+        <td><div id="eq_lauter_volume"></div></td>
+        <td style="vertical-align: top; float: right;">Extra water bij koken L:</td>
+        <td><div id="eq_top_up_kettle"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right;">Filterkuip verlies L:</td>
+        <td><div id="eq_lauter_deadspace"></div></td>
+        <td style="vertical-align: top; float: right;">Hopfactor %:</td>
+        <td><div id="eq_hop_utilization"></div></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="2">Koelen</th>
+        <td style="vertical-align: top; float: right;">Volume eind koken L:</td>
+        <td><div id="eq_batch_size"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right;">Trub verlies kookketel L:</td>
+        <td><div id="eq_trub_chiller_loss"></div></td>
+        <td style="vertical-align: top; float: right;">Brouwzaalrendement %:</td>
+        <td><div id="eq_efficiency"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right;">Extra water in gistvat:</td>
+	<td><div id="eq_top_up_water"></div></td>
+        <td colspan="2"></td>
+       </tr>
+      </table>
+     </div>
+    </div>
+
+    <div> <!-- tab vergistbaar -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Kleur EBC:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_color2"></div><div id="bcolor2" class='ebccolor'> </div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Percentage moutstort:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="perc_malts"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Begin SG:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_og2"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Percentage suiker:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="perc_sugars"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Maisch KG:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="mash_kg"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Percentage cara:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="perc_cara"></div></td>
+       </tr>
+       <tr>
+	<td colspan="2"> </td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Lintner totaal:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="ferm_lintner"></div></td>
+       </tr>
+       <tr>
+        <td align="center" colspan="4"><div id="fermentableGrid"></div></td>
+       </tr>
+      </table>
+     </div>
+    </div> <!-- tab vergistbaar -->
+
+    <div> <!-- tab hoppen -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheid IBU:</td>
+        <td style="padding: 3px;"><div id="est_ibu2"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Smaak bijdrage:</td>
+        <td style="padding: 3px;"><div id="hop_flavour"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Aroma bijdrage:</td>
+        <td style="padding: 3px;"><div id="hop_aroma"></div></td>
+       </tr>
+       <tr>
+        <td align="center" colspan="6"><div id="hopGrid"></div></td>
+       </tr>
+      </table>
+     </div>
+    </div> <!-- tab hoppen -->
+
+    <div> <!-- tab misc -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr><td>&nbsp;</td></tr>
+       <tr><td align="center"><div id="miscGrid"></div></td></tr>
+      </table>
+     </div>
+    </div> <!-- tab misc -->
+
+    <div> <!-- tab gisten -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Verwacht FG en ABV:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="est_fg2"></div><div style="float: left; margin-left: 10px;" id="est_abv2"></div></td>
+        <td align="center" colspan="5" rowspan="5">
+         <div id="propagator">
+          <table style="width: 100%;">
+           <caption>Giststarter stappen</caption>
+           <tr>
+            <td style="width: 40px; padding: 3px;">Stap</td>
+            <td align="left" style="vertical-align: top; padding: 3px;">Methode</td>
+            <td style="width: 120px; padding: 3px;">Volume</td>
+            <td style="width: 120px; padding: 3px;">Inj. factor</td>
+            <td style="width: 120px; padding: 3px;">Nieuwe cellen</td>
+            <td style="width: 120px; padding: 3px;">Totaal cellen</td>
+            <td style="width: 120px; padding: 3px;">Groei factor</td>
+           </tr>
+           <tr>
+            <td align="center">1</td>
+            <td><input id="prop1_type" readonly /><div id="r1_pmpt">Niet nodig</div></td>
+            <td><div id="prop1_volume"></div></td>
+            <td><div style="float: left;" id="prop1_irate"></div><div style="float: left;" id="r1_irate"></div></td>
+            <td><div id="prop1_ncells"></div></td>
+            <td><div style="float: left;" id="prop1_tcells"></div><div style="float: left;" id="r1_tcells"></div></td>
+            <td><div style="float: left;" id="prop1_growf"></div><div style="float: left;" id="r1_growf"></div></td>
+           </tr>
+           <tr>
+            <td align="center">2</td>
+            <td><input id="prop2_type" readonly /><div id="r2_pmpt">Niet nodig</div></td>
+            <td><div id="prop2_volume"></div></td>
+            <td><div style="float: left;" id="prop2_irate"></div><div style="float: left;" id="r2_irate"></div></td>
+            <td><div id="prop2_ncells"></div></td>
+            <td><div style="float: left;" id="prop2_tcells"></div><div style="float: left;" id="r2_tcells"></div></td>
+            <td><div style="float: left;" id="prop2_growf"></div><div style="float: left;" id="r2_growf"></div></td>
+           </tr>
+           <tr>
+            <td align="center">3</td>
+            <td><input id="prop3_type" readonly /><div id="r3_pmpt">Niet nodig</div></td>
+            <td><div id="prop3_volume"></div></td>
+            <td><div style="float: left;" id="prop3_irate"></div><div style="float: left;" id="r3_irate"></div></td>
+            <td><div id="prop3_ncells"></div></td>
+            <td><div style="float: left;" id="prop3_tcells"></div><div style="float: left;" id="r3_tcells"></div></td>
+            <td><div style="float: left;" id="prop3_growf"></div><div style="float: left;" id="r3_growf"></div></td>
+           </tr>
+           <tr>
+            <td align="center">4</td>
+            <td><input id="prop4_type" readonly /><div id="r4_pmpt">Niet nodig</div></td>
+            <td><div id="prop4_volume"></div></td>
+            <td><div style="float: left;" id="prop4_irate"></div><div style="float: left;" id="r4_irate"></div></td>
+            <td><div id="prop4_ncells"></div></td>
+            <td><div style="float: left;" id="prop4_tcells"></div><div style="float: left;" id="r4_tcells"></div></td>
+            <td><div style="float: left;" id="prop4_growf"></div><div style="float: left;" id="r4_growf"></div></td>
+           </tr>
+          </table>
+         </div>
+        </td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Gist productie datum:</td>
+        <td style="padding: 3px;"><div id="yeast_prod_date"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Gist conditie %:</td>
+        <td style="padding: 3px;"><div id="starter_viability"></div></td>
+       </tr>
+       <tr class="primary_dry">
+        <td style="vertical-align: top; float: right; padding: 3px;">Gist nodig gram:</td>
+        <td style="padding: 3px;"><div id="yeast_grams"></div></td>
+       </tr>
+       <tr class="primary_dry">
+        <td style="vertical-align: top; float: right; padding: 3px;">Ent hoeveelheid gr/hl:</td>
+        <td style="padding: 3px;"><div id="yeast_gr_hl"></div></td>
+       </tr>
+       <tr class="primary_liquid">
+        <td style="vertical-align: top; float: right; padding: 3px;">Gistcellen miljard:</td>
+        <td style="padding: 3px;"><div id="yeast_cells"></div></td>
+       </tr>
+       <tr class="primary_liquid">
+        <td style="vertical-align: top; float: right; padding: 3px;">Pitch rate:</td>
+        <td style="padding: 3px;"><div id="yeast_pitchrate"></div></td>
+       </tr>
+       <tr class="primary_liquid">
+        <td style="vertical-align: top; float: right; padding: 3px;">Cellen nodig miljard:</td>
+        <td style="padding: 3px;"><div id="need_cells"></div></td>
+       </tr>
+       <tr class="primary_liquid">
+        <td style="vertical-align: top; float: right; padding: 3px;">Pitch cellen/ml &deg;P:</td>
+        <td style="padding: 3px;"><div id="plato_cells"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Starter type:</td>
+	<td style="padding: 3px;"><input id="starter_type" readonly /></td>
+ 	<td style="vertical-align: top; float: right; padding: 3px;">Starter SG:</td>
+	<td style="padding: 3px;"><div id="starter_sg"></div></td>
+        <td></td>
+       </tr>
+       <tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
+       <tr><td align="center" colspan="7"><div id="yeastGrid"></div></td></tr>
+      </table>
+     </div>
+    </div> <!-- tab gisten -->
+
+    <div> <!-- tab maischen -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Maischchema:</td>
+	<td colspan="3" align="left" style="vertical-align: top; padding: 3px;"><input id="mash_name" readonly /></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Volume van de maisch L:</td>
+        <td style="padding: 3px;"><div id="est_mashvol"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Tijdsduur maischen:</td>
+        <td align="left" style="vertical-align: top; padding: 3px;"><input style="text-align:right" readonly="1" id="est_mashtime" /></td>
+       </tr>
+       <tr><td colspan="4">&nbsp;</td></tr>
+       <tr><td align="center" colspan="4" style="padding: 3px;"><div id="mashGrid"></div></td></tr>
+      </table>
+     </div>
+    </div> <!-- tab maischen -->
+
+    <div> <!-- tab water -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td align="center" colspan="9">
+         <div id='water_totals'>
+          <table style="width: 100%;">
+           <caption>Water overzicht</caption>
+           <tr>
+	    <td align="left" style="vertical-align: top; padding: 3px;">Water profiel</td>
+            <td style="width: 50px; padding: 3px;">Spoel</td>
+            <td style="width: 97px; padding: 3px;">Volume</td>
+            <td style="width: 77px; padding: 3px;">Ca</td>
+	    <td style="width: 77px; padding: 3px;">Mg</td>
+            <td style="width: 77px; padding: 3px;">HCO3</td>
+	    <td style="width: 77px; padding: 3px;">CaCO3</td>
+            <td style="width: 77px; padding: 3px;">Na</td>
+            <td style="width: 77px; padding: 3px;">Cl</td>
+            <td style="width: 77px; padding: 3px;">SO4</td>
+	    <td style="width: 77px; padding: 3px;">pH</td>
+            <td style="width: 77px; padding: 3px;">Hardheid</td>
+            <td style="width: 77px; padding: 3px;">RA</td>
+           </tr>
+           <tr>
+	    <td><input readonly="1" id="w1_name" /></td>
+            <td><div style='margin-left: 10px;' id='w1_button'></div></td>
+            <td><div id="w1_amount"></div></td>
+            <td><div id="w1_calcium"></div></td>
+	    <td><div id="w1_magnesium"></div></td>
+	    <td><div id="w1_bicarbonate"></div></td>
+            <td><div id="w1_total_alkalinity"></div></td>
+            <td><div id="w1_sodium"></div></td>
+            <td><div id="w1_chloride"></div></td>
+            <td><div id="w1_sulfate"></div></td>
+	    <td><div id="w1_ph"></div></td>
+            <td><div id="w1_hardness"></div></td>
+            <td><div id="w1_ra"></div></td>
+           </tr>
+           <tr>
+	    <td><input readonly="1" id="w2_name" /></td>
+            <td><div style='margin-left: 10px;' id='w2_button'></div></td>
+            <td><div id="w2_amount"></div></td>
+            <td><div id="w2_calcium"></div></td>
+	    <td><div id="w2_magnesium"></div></td>
+            <td><div id="w2_bicarbonate"></div></td>
+	    <td><div id="w2_total_alkalinity"></div></td>
+            <td><div id="w2_sodium"></div></td>
+            <td><div id="w2_chloride"></div></td>
+            <td><div id="w2_sulfate"></div></td>
+	    <td><div id="w2_ph"></div></td>
+            <td><div id="w2_hardness"></div></td>
+            <td><div id="w2_ra"></div></td>
+           </tr>
+           <tr>
+	    <td style="vertical-align: top; padding: 3px; float: left;">Gemengd water:</td>
+            <td><div style='margin-left: 10px;' id='wg_button'></div></td>
+            <td><div id="wg_amount"></div></td>
+            <td><div id="wg_calcium"></div></td>
+	    <td><div id="wg_magnesium"></div></td>
+            <td><div id="wg_bicarbonate"></div></td>
+	    <td><div id="wg_total_alkalinity"></div></td>
+            <td><div id="wg_sodium"></div></td>
+            <td><div id="wg_chloride"></div></td>
+            <td><div id="wg_sulfate"></div></td>
+	    <td><div id="wg_ph"></div></td>
+            <td><div id="wg_hardness"></div></td>
+            <td><div id="wg_ra"></div></td>
+           </tr>
+           <tr>
+	    <td style="vertical-align: top; padding: 3px; float: left;">Behandeld maisch water:</td>
+            <td></td>
+            <td><div></div></td>
+            <td><div id="wb_calcium"></div></td>
+	    <td><div id="wb_magnesium"></div></td>
+            <td><div id="wb_bicarbonate"></div></td>
+	    <td><div id="wb_total_alkalinity"></div></td>
+            <td><div id="wb_sodium"></div></td>
+            <td><div id="wb_chloride"></div></td>
+            <td><div id="wb_sulfate"></div></td>
+	    <td><div id="wb_ph"></div></td>
+            <td><div id="wb_hardness"></div></td>
+            <td><div id="wb_ra"></div></td>
+           </tr>
+           <tr>
+	    <td style="vertical-align: top; padding: 3px; float: left;">Resultaat:</td>
+            <td></td>
+            <td><div></div></td>
+            <td><div id="wr_calcium"></div></td>
+            <td><div id="wr_magnesium"></div></td>
+            <td><div id="wr_bicarbonate"></div></td>
+	    <td><div id="wr_total_alkalinity"></div></td>
+            <td><div id="wr_sodium"></div></td>
+            <td><div id="wr_chloride"></div></td>
+            <td><div id="wr_sulfate"></div></td>
+	    <td><div id="wr_ph"></div></td>
+            <td></td>
+            <td></td>
+	   </tr>
+           <tr>
+            <td style="vertical-align: top; padding: 3px; float: left;">Behandeld spoelwater:</td>
+            <td></td>
+            <td><div id="sw_amount"></div></td>
+            <td><div id="sw_calcium"></div></td>
+            <td><div id="sw_magnesium"></div></td>
+            <td><div id="sw_bicarbonate"></div></td>
+            <td><div id="sw_total_alkalinity"></div></td>
+            <td><div id="sw_sodium"></div></td>
+            <td><div id="sw_chloride"></div></td>
+            <td><div id="sw_sulfate"></div></td>
+            <td><div id="sw_ph"></div></td>
+            <td><div id="sw_hardness"></div></td>
+            <td><div id="sw_ra"></div></td>
+           </tr>
+          </table>
+         </div>
+        </td>
+       </tr>
+       <tr>
+	<th style="text-align: center;" colspan="3">Brouwzouten</th>
+	<th colspan="3"></th>
+        <th style="text-align: center;" colspan="3">Spoelwater</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">CaCl2 gr:</td>
+	<td style="padding: 3px;"><div id="wa_cacl2"></div></td>
+        <td style="padding: 3px;"><div id="ss_cacl2"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Bitterheidsindex:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="tgt_bu"></div></td>
+        <td style="padding: 3px;"><div style="float: left;" id="wr_bu"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Auto bereken:</td>
+        <td style="padding: 3px;"><div id="calc_acid"></div></td>
+        <td></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">CaSO4 gr:</td>
+	<td style="padding: 3px;"><div id="wa_caso4"></div></td>
+        <td style="padding: 3px;"><div id="ss_caso4"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Richtgetal SO4:Cl:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="tgt_so4_cl"></div></td>
+        <td style="padding: 3px;"><div style="float: left;" id="wrt_so4_cl"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;"><div class='c_mashph'>Gewenst maish pH:</div></td>
+        <td style="padding: 3px;"><div id="mash_ph" class='c_mashph'></div></td>
+        <td></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">MgSO4 gr:</td>
+	<td style="padding: 3px;"><div id="wa_mgso4"></div></td>
+        <td style="padding: 3px;"><div id="ss_mgso4"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Huidig SO4:Cl:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="got_so4_cl"></div></td>
+        <td style="padding: 3px;"><div style="float: left;" id="wr_so4_cl"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Aanzuren met:</td>
+        <td style="padding: 3px;"><input readonly="1" id="wa_acid_name" /></td>
+        <td style="padding: 3px;"><div style="float: left;" id="wa_acid_perc"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">NaCl gr:</td>
+	<td style="padding: 3px;"><div id="wa_nacl"></div></td>
+        <td style="padding: 3px;"><div id="ss_nacl"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Voor koken pH:</td>
+        <td style="padding: 3px;"><div id="preboil_ph"></div></td>
+        <td></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Zuur hoeveelheid:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="wa_acid"></div></td>
+        <td></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">MgCl2 gr:</td>
+	<td style="padding: 3px;"><div id="wa_mgcl2"></div></td>
+        <td style="padding: 3px;"><div id="ss_mgcl2"></div></td>
+        <td colspan="3"></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Gewenst spoel pH:</td>
+        <td style="padding: 3px;"><div id="sparge_ph"></div></td>
+        <td></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">NaHCO3 gr:</td>
+	<td style="padding: 3px;"><div id="wa_nahco3"></div></td>
+        <td colspan="4"></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Aanzuren met:</td>
+        <td style="padding: 3px;"><input readonly="1" id="sparge_acid_type" /></td>
+        <td style="padding: 3px;"><div id="sparge_acid_perc"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">CaCO3 gr:</td>
+	<td style="padding: 3px;"><div id="wa_caco3"></div></td>
+        <td colspan="4"></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Zuur hoeveelheid:</td>
+        <td style="padding: 3px;"><div id="sparge_acid_amount"></div></td>
+        <td></td>
+       </tr>
+      </table>
+     </div>
+    </div> <!-- tab water -->
+
+    <div style="overflow: hidden;"> <!-- Brewday -->
+     <table style="width: 100%;">
+      <tr>
+       <td style="vertical-align: top; float: right; padding: 3px;">Brouwdag start:</td>
+       <td align="left" colspan="2" style="vertical-align: top;"><div id="brew_date_start"></div></td>
+       <td style="vertical-align: top; float: right; padding: 3px;">Brouwdag eind:</td>
+       <td align="left" colspan="2" style="vertical-align: top;"><div id="brew_date_end"></div></td>
+      </tr>
+      <tr>
+       <td colspan="6"> </td>
+      </tr>
+      <tr>
+       <th style="text-align: center;" colspan="2">Maischen</th>
+       <th style="text-align: center;" colspan="4"><div id="brew_pmpt_koken">Koken</div></th>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Maisch pH:</td>
+       <td><div style="float: left;" id="brew_mash_ph"></div><div style="float: left; margin-left: 10px;" id="est_mash_ph"></div></td>
+       <td style="vertical-align: top; float: right;">Voor koken pH:</td>
+       <td><div id="brew_preboil_ph"></div></td>
+       <td style="vertical-align: top; float: right;">Na koken pH:</td>
+       <td><div id="brew_aboil_ph"></div></td>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Maisch SG:</td>
+       <td><div style="float: left;" id="brew_mash_sg"></div><div style="float: left; margin-left: 10px;" id="est_mash_sg"></div></td>
+       <td style="vertical-align: top; float: right;">Voor koken SG:</td>
+       <td><div style="float: left;" id="brew_preboil_sg"></div><div style="float: left; margin-left: 10px;" id="est_pre_sg"></div></td>
+       <td style="vertical-align: top; float: right;">Na koken SG:</td>
+       <td><div style="float: left;" id="brew_aboil_sg"></div><div style="float: left; margin-left: 10px;" id="est_og3"></div></td>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Maisch rendement %:</td>
+       <td><div id="brew_mash_efficiency"></div></td>
+       <td style="vertical-align: top; float: right;">Voor koken vol@100&deg;C:</td>
+       <td><div style="float: left;" id="brew_preboil_volume"></div><div style="float: left; margin-left: 10px;" id="est_pre_vol"></div></td>
+       <td style="vertical-align: top; float: right;">Na koken vol@100&deg;C:</td>
+       <td><div style="float: left;" id="brew_aboil_volume"></div><div style="float: left; margin-left: 10px;" id="est_a_vol"></div></td>
+      </tr>
+      <tr>
+       <td colspan="2"> </td>
+       <td style="vertical-align: top; float: right;">Voor koken rendement %:</td>
+       <td><div id="brew_preboil_efficiency"></div></td>
+       <td style="vertical-align: top; float: right;">Na koken rendement %:</td>
+       <td><div id="brew_aboil_efficiency"></div></td>
+      </tr>
+      <tr>
+       <td colspan="6">&nbsp;</td>
+      </tr>
+      <tr>
+       <th style="text-align: center;" colspan="2">Spoelen en filteren</th>
+       <th style="text-align: center;" colspan="4">Koelen en whirlpoolen</th>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Spoelwater &deg;C:</td>
+       <td><div id="brew_sparge_temperature"></div></td>
+       <td style="vertical-align: top; float: right;">Whirlpool 85..100&deg;C min:</td>
+       <td><div id="brew_whirlpool9"></div></td>
+       <td style="vertical-align: top; float: right;">Koelen tot &deg;C:</td>
+       <td><div id="brew_cooling_to"></div></td>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Spoelwater voorraad L:</td>
+       <td><div id="brew_sparge_volume"></div></td>
+       <td style="vertical-align: top; float: right;">Whirlpool 72..79&deg;C min:</td>
+       <td><div id="brew_whirlpool7"></div></td>
+       <td style="vertical-align: top; float: right;">Koelen met:</td>
+       <td><input readonly="1" id="brew_cooling_method" /></td>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Spoelwater nodig L:</td>
+       <td><div id="brew_sparge_est"></div></td>
+       <td style="vertical-align: top; float: right;">Whirlpool 60..66&deg;C min:</td>
+       <td><div id="brew_whirlpool6"></div></td>
+       <td style="vertical-align: top; float: right;">Koelen minuten:</td>
+       <td><div id="brew_cooling_time"></div></td>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Spoelwater pH:</td>
+       <td><div id="brew_sparge_ph"></div></td>
+       <td style="vertical-align: top; float: right;">Whirlpool koud min:</td>
+       <td><div id="brew_whirlpool2"></div></td>
+       <td colspan="2"> </td>
+      </tr>
+      <tr>
+       <td colspan="6">&nbsp;</td>
+      </tr>
+      <tr>
+       <th style="text-align: center;" colspan="2">Beluchten</th>
+       <th style="text-align: center;" colspan="4">Naar gistvat</th>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Beluchten met:</td>
+       <td><input readonly="1" id="brew_aeration_type" /></td>
+       <td style="vertical-align: top; float: right;">Koeler en trub verlies L:</td>
+       <td><div id="brew_fermenter_tcloss"></div></td>
+       <td style="vertical-align: top; float: right;">SG in gistvat:</td>
+       <td><div id="brew_fermenter_sg"></div></td>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Beluchten tijd min:</td>
+       <td><div id="brew_aeration_time"></div></td>
+       <td style="vertical-align: top; float: right;">Extra water in gistvat L:</td>
+       <td><div id="brew_fermenter_extrawater"></div></td>
+       <td style="vertical-align: top; float: right;">Kleur in gistvat EBC:</td>
+       <td><div style="float: left;" id="brew_fermenter_color"></div><div style="float: left; margin-left: 10px;" id="bcolorf" class='ebccolor'> </div></td>
+      </tr>
+      <tr>
+       <td style="vertical-align: top; float: right;">Beluchten snelheid:</td>
+       <td><div id="brew_aeration_speed"></div></td>
+       <td style="vertical-align: top; float: right;">Volume naar gistvat L:</td>
+       <td><div id="brew_fermenter_volume"></div></td>
+       <td style="vertical-align: top; float: right;">Bitterheid in gistvat IBU:</td>
+       <td><div style="float: left;" id="brew_fermenter_ibu"></div></td>
+      </tr>
+     </table>
+    </div> <!-- Brewday -->
+
+    <div> <!-- Vergisten -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+	<td style="width: 30%;"> </td>
+        <td style="width: 20%;"> </td>
+        <td style="width: 30%;"> </td>
+        <td style="width: 20%;"> </td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="4">Hoofdvergisting</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Begin vergisting SG:</td>
+	<td align="left" colspan="3" style="vertical-align: top;"><div id="brew_fermenter_sg2"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Start temperatuur hoofdvergisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_start_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Piek temperatuur hoofdvergisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_max_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind temperatuur hoofdvergisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind hoofdvergisting SG:</td>
+	<td align="left" colspan="3" style="vertical-align: top;"><div id="primary_end_sg"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind hoofdvergisting/overhevelen:</td>
+	<td align="left" style="vertical-align: top;"><div id="primary_end_date"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad:</td>
+        <td align="left" style="vertical-align: top;"><div id="primary_svg"></div></td>
+       </tr>
+       <tr>
+        <td colspan="4"><hr></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="4">Nagisting</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Temperatuur nagisting &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="secondary_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind nagisting SG:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="secondary_end_sg"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Eind nagisting/start lageren:</td>
+        <td align="left" style="vertical-align: top;"><div id="secondary_end_date"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad %:</td>
+        <td align="left" style="vertical-align: top;"><div id="secondary_svg"></div></td>
+       </tr>
+       <tr>
+        <td colspan="4"><hr></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="4">Lageren</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Temperatuur lageren &deg;C:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="tertiary_temp"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Het verwachte eind SG:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="est_fg3"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Het behaalde eind SG:</td>
+	<td align="left" colspan="3" style="vertical-align: top;"><div id="fg"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Alcoholgehalte voor hergisting vol.%:</td>
+        <td align="left" style="vertical-align: top;"><div id="final_abv"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schijnbare vergistingsgraad %:</td>
+        <td align="left" style="vertical-align: top;"><div id="final_svg"></div></td>
+       </tr>
+      </table>
+      <div style="float: right; margin-top: 55px; margin-bottom: 5px;">
+       <input style="margin-right: 100px;" type="button" id="FLog"  value="Klimaatkast log" />
+       <input style="margin-right: 475px;" type="button" id="ILog" value="Vergisting log" />
+      </div>
+     </div>
+    </div> <!-- Vergisten -->
+
+    <div> <!-- Verpakken -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Datum:</td>
+	<td align="left" style="vertical-align: top;"><div id="package_date"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Aanbevolen volume CO2:</td>
+        <td style="padding: 3px;"><div style="float: left;" id="st_carb_min2"></div><div style="float: left; margin-left: 5px;" id="st_carb_max2"></div></td>
+       </tr>
+       <tr>
+        <td colspan="4"><hr></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="4">Verdunnen of infusie</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Volume na vergisting L:</td>
+        <td align="left" colspan="3" style="vertical-align: top;"><div id="package_volume"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Toevoeging Liter:</td>
+        <td align="left" style="vertical-align: top;"><div id="package_infuse_amount"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Toevoeging ABV %:</td>
+        <td align="left" style="vertical-align: top;"><div id="package_infuse_abv"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Toevoeging omschrijving:</td>
+        <td align="left" colspan="3" style="vertical-align: top; padding: 3px;"><input id="package_infuse_notes" /></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Alcohol volume %:</td>
+        <td align="left" style="vertical-align: top;"><div id="package_abv"></div></td>
+        <td style="vertical-align: top; float: right;">Bij verpakken pH:</td>
+        <td align="left" style="vertical-align: top;"><div id="package_ph"></div></td>
+       </tr>
+       <tr>
+        <td colspan="4"><hr></td>
+       </tr>
+       <tr>
+        <th style="text-align: center;" colspan="2">Flessen</th>
+        <th style="text-align: center;" colspan="2">Fusten</th>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Hoeveelheid Liter:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_amount"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Hoeveelheid Liter:</td>
+	<td align="left" style="vertical-align: top;"><div id="keg_amount"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Gewenst volume CO2:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_carbonation"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Gewenst volume CO2:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_carbonation"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Suiker:</td>
+        <td align="left" style="vertical-align: top;"><input readonly="1" id="bottle_priming_sugar" /></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Suiker:</td>
+        <td align="left" style="vertical-align: top;"><input readonly="1" id="keg_priming_sugar" /></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Toevoegen suiker g/L:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_priming_amount"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Toevoegen suiker g/L:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_priming_amount"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Suiker totaal gram:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_priming_total"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Suiker totaal gram:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_priming_total"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Suikeroplossing water L:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_priming_water"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Suikeroplossing water L:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_priming_water"></div></td>
+       </tr>
+       <tr>
+        <td colspan="2"></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Op druk brengen met CO2:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_forced_carb"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Verwachte flesdruk in bar:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_pressure"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Druk op fust bar:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_pressure"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Alcoholgehalte flessen vol.%:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_abv"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Alcoholgehalte fusten vol.%:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_abv"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Hergisting temperatuur:</td>
+        <td align="left" style="vertical-align: top;"><div id="bottle_carbonation_temp"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Keg temperatuur:</td>
+        <td align="left" style="vertical-align: top;"><div id="keg_carbonation_temp"></div></td>
+       </tr>
+      </table>
+      <div style="float: right; margin-top: 20px; margin-bottom: 5px;">
+       <input style="margin-right: 575px;" type="button" id="CLog" value="Hergisting log" />
+      </div>
+     </div>
+    </div> <!-- Verpakken -->
+
+    <div> <!-- Proeven -->
+     <div style="overflow: hidden;">
+      <table style="width: 100%;">
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Datum:</td>
+	<td align="left" style="vertical-align: top;"><div id="taste_date"></div></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Cijfer:</td>
+        <td align="left" style="vertical-align: top;"><div id="taste_rate"></div></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Kleur:</td>
+	<td style="padding: 3px;"><textarea id="taste_color" readonly></textarea></td>
+        <td style="vertical-align: top; float: right; padding: 3px;">Helderheid:</td>
+        <td style="padding: 3px;"><textarea id="taste_transparency" readonly></textarea></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Schuim:</td>
+        <td colspan="3" style="padding: 3px;"><textarea id="taste_head" readonly></textarea></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Aroma:</td>
+        <td colspan="3" style="padding: 3px;"><textarea id="taste_aroma" readonly></textarea></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Smaak:</td>
+        <td colspan="3" style="padding: 3px;"><textarea id="taste_taste" readonly></textarea></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Nasmaak:</td>
+        <td colspan="3" style="padding: 3px;"><textarea id="taste_aftertaste" readonly></textarea></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Mondgevoel:</td>
+        <td colspan="3" style="padding: 3px;"><textarea id="taste_mouthfeel" readonly></textarea></td>
+       </tr>
+       <tr>
+        <td style="vertical-align: top; float: right; padding: 3px;">Oordeel:</td>
+        <td colspan="3" style="padding: 3px;"><textarea id="taste_notes" readonly></textarea></td>
+       </tr>
+      </table>
+     </div>
+    </div> <!-- Proeven -->
+
+   </div> <!-- Tabs -->
+
+<?php
+page_footer();
+?>

mercurial