PageSourceSearch

https://quickblock.uk/wp-content/plugins/quickblock-blockulator//quickblock-blockulator.js?ver=1.17

js quickblock.uk collected 2026-10-08 19:01:48 UTC 54,514 bytes, 1,298 lines download raw bytes

1/**
2 * Plugin Name: Quickblock Blockulator
3 * Plugin URI: https://quickblock.uk
4 * Description: This plugin adds a tool to calculate the required amount of Quickblocks needed for a wall or structure.
5 * Version: 1.0
6 * Author: Agency of None / Rick Curran
7 * Author URI: https://agencyofnone.com
8 */
9
10( function($) {
11	
12	// Block dimensions in mm
13	const fullLength = 456;
14	const halfLength = 228;
15	const blockHeight = 228;
16	
17	
18	$( '.numeric' ).keyup( function( event ) {
19		var val = $( this ).val();
20		$( this ).removeClass( 'alert' ); // Remove any `alert` class
21		if ( isNaN( val ) ) {
22			 val = val.replace(/[^0-9\.]/g, '' );
23			 if ( val.split( '.' ).length > 2 ) { 
24				 val = val.replace(/\.+$/, '' );
25			 }
26		}
27		$( this ).val( val.replace( '-', '' ) ); 
28	});
29	
30	// Define the MROUND function to round to the nearest specified multiple
31	function mRound(value, multiple) {
32		return Math.round(value / multiple) * multiple;
33	}
34
35	// Define the ROUND function to round to the nearest integer
36	function round(value, decimals) {
37		const factor = Math.pow(10, decimals);
38		return Math.round(value * factor) / factor;
39	}
40	
41	// Define the ROUNDUP function to round up to the nearest integer
42	function roundUp(value) {
43		return Math.ceil(value);
44	}
45	
46	// Define the ISODD function to check if a number is odd
47	function isOdd(number) {
48		return number % 2 !== 0;
49	}
50	
51	
52	/*
53	 * RICK TEST VERSIONS
54	 */
55	
56	/*
57	 * 
58	 LOGIC FOR CALCULATING STRUCTURES
59	 Ryan's specs for Window & Door:
60	 Window: 46cm x 46cm
61	 Door: 90cm Width x 200cm Height
62	 
63	 Actual window = 456mm x 456mm : -3 Full blocks, + 2 Half blocks
64	 - To cut this out of a wall will chop out the equivalent of 2 full blocks, but with the staggered block arrangement this means losing 3 x Full blocks but compensates with 2 Half blocks either side of one row of the window.
65	 
66	 Actual door = 912mm x 2052mm : -18 Full blocks, + 8 Half blocks
67	 - To cut this out of a door will chop out the equivalent of 18 full blocks, but with the staggered block arrangement this means losing 22 x Full blocks but compensates with 8 Half blocks either side of four rows of the door (there is also an alternative arrangement 23 x Full blocks are lost and compensate with 10 half blocks either side of five rows of the door - Which is needed? Does it matter? Needs to be determined!!!).
68	 
69	 So, is the process to figure out the structure as follows:
70	 - The Structure uses 4 walls, 2 for the length walls and 2 for the width walls. All 4 walls are the same height.
71	 
72	 - Depending on whether the walls are an even or odd number affects the staggering of the blocks so that they can intersect:
73	 
74	 	- If EVEN then all four walls need the same amount of staggered blocks to intersect correctly so would use the following standard logic:
75	 		- Get the block count for a length wall without the staggered Half blocks, assign values to Walls 1 and 2.
76			- Get the block count for a width wall without the staggered Half blocks, assign values to Walls 3 and 4.
77		- If ODD then the length and width walls need different amounts of staggered blocks to intersect correctly so would use the following logic:
78			- 
79	 
80	 - For a structure we need to have staggered Half block spaces for the intersection at the corners, this is done 1 per row of the height of the wall, we need to remove this amount from each wall, so for an 8 row wall we remove 8 x Half blocks.
81	 
82	 - If there is 1 window specified then subtract 3 from the count of Full blocks and add 2 to the count of Half blocks for ONE wall;
83		- If there is another 1 window specified then do the same for another wall;
84		- Repeat if there are more windows (!!!it seems like there should be a limit for how many windows can be defined within certain Width / Height ranges, there is only so much window space that can possibly be subtracted from a given wall!!!)
85	
86	 
87	 */
88	
89	/*function renderWall( cap_content_arr, row_content_arr, mode ) {
90		if ( $( '#wall-preview-container' ).length > 0 ) {
91		
92			if ( mode != 'structure' ) {
93				let c_char_count = 1;
94				cap_content_arr.forEach( ( item, index ) => {
95					let cap = '';
96					if ( item == 'C' ) {
97						cap = '<div class="block cap" style="display:inline-block;width:40px;height:14px;background-color:#444;border:1px solid #fff;text-align:center;font-size:10px;line-height:1;padding-top:1px;padding-bottom:1px;color:#fff;">' + c_char_count + '</div>';
98
99						if ( index === cap_content_arr.length - 1 ) {
100							$( '#wall-preview-container' ).append( cap + '<br>' );
101						} else {
102							$( '#wall-preview-container' ).append( cap );
103						}
104						c_char_count++;
105					}
106
107				});
108			}
109
110			let f_char_count = 1;
111			let h_char_count = 1;
112			row_content_arr.forEach( ( item ) => {
113				let block = '';
114				if ( item == 'F' ) {
115					block = '<div class="block full" style="display:inline-block;width:40px;height:20px;background-color:#003626;border:1px solid #fff;text-align:center;font-size:12px;line-height:1;padding-top:4px;padding-bottom:4px;color:#fff;">' + f_char_count + '</div>';
116					f_char_count++;
117				} else if ( item == 'H' ) {
118					let h_class = 'background-color:#00AB3F;border:1px solid #fff;color:#fff;';
119					if ( mode == 'structure' ) {
120						h_class = 'background-color:transparent;border:1px solid transparent;color:transparent;';
121					}
122
123					block = '<div class="block half" style="display:inline-block;width:20px;height:20px;' + h_class + 'text-align:center;font-size:12px;line-height:1;padding-top:4px;padding-bottom:4px;">' + h_char_count + '</div>';
124					h_char_count++;
125				} else if ( item == 'B' ) {
126					block = '<br>';
127					//block = '<div class="break" style="width:0;height:0;clear:both;"></div>';
128				}
129				$( '#wall-preview-container' ).append( block );
130			});
131
132			$( '#wall-preview-container' ).append( '<hr style="margin-top:1rem;margin-bottom:1rem;">' );
133		}
134		
135	}*/
136	
137	function calculateWallBlocks(wallHeight, wallLength, mode) {
138		
139		if ( mode == 'structure' ) {
140			console.log( 'CALCULATING WALL FOR STRUCTURE...' );
141		}
142
143		// Round the width and height to the nearest multiples of block sizes
144		let adjustedLength = Math.round(wallLength / halfLength) * halfLength;
145		let adjustedHeight = Math.round(wallHeight / blockHeight) * blockHeight;
146		
147		// Initialize block counters
148		let fullCount = 0;
149		let halfCount = 0;
150
151		// Calculate the number of rows
152		const rows = adjustedHeight / blockHeight;
153
154		let adjust_counts = false; 
155		
156		let row_content = '';
157		let row_content_arr = [];
158		let f_count = 0;
159		let h_count = 0;
160
161		for ( let i = 0; i < rows; i++ ) {
162			let remainingWidth = adjustedLength;
163
164			// Use full blocks first
165			fullCount += Math.floor(remainingWidth / fullLength);
166			remainingWidth %= fullLength;
167			console.log( 'Calculating fullCount... ' + fullCount );
168			
169			// Use half blocks for the remainder
170			halfCount += Math.floor(remainingWidth / halfLength);
171			console.log( 'Calculating halfCount... ' + halfCount );
172			
173			//console.log( 'i: ' + i );
174			//console.log( 'halfCount: ' + halfCount );
175			
176			if ( i == 0 && halfCount == 0 ) {
177				adjust_counts = true; // If no half blocks are in use then we need to adjust counts so set variable to true
178			}
179			
180			// IF there are 0 (ZERO) Half blocks then we need to alternate every row to use to a half block at each end instead of all being full blocks
181			if ( adjust_counts == true && isOdd( i ) ) {
182				console.log( 'Adjust Counts... ' );
183				fullCount--;
184				halfCount++;
185				halfCount++;
186			}
187			
188			// Attempt to render the layout!
189			let f = 0;
190			let h = 0;
191
192			if ( i == 0 ) {
193				f_count = fullCount;
194				h_count = halfCount;
195			}
196			
197			// We render a preview of a wall with half blocks at alternating ends of each row:
198			if ( adjust_counts == false ) {
199				if ( isOdd( i ) ) {
200					//console.log( 'ODD:' );
201					row_content = row_content + '◻'; // HALF
202					row_content_arr.push( 'H' ); // HALF
203					while (f < f_count) {
204						row_content = row_content + '▭'; // FULL
205						row_content_arr.push( 'F' ); // FULL
206						f++;
207					}
208				} else {
209					//console.log( 'EVEN:' );
210					while (f < f_count) {
211						row_content = row_content + '▭'; // FULL
212						row_content_arr.push( 'F' ); // FULL
213						f++;
214					}
215					row_content = row_content + '◻'; // HALF
216					row_content_arr.push( 'H' ); // HALF
217				}
218				row_content = row_content + '\n';
219				row_content_arr.push( 'B' ); // BREAK
220			}
221
222			// We render a preview of a wall with each alternate row having a half block at each end:
223			if ( adjust_counts == true ) {
224				if ( isOdd( i ) ) {
225					//console.log( 'ODD:' );
226					row_content = row_content + '◻'; // HALF
227					row_content_arr.push( 'H' ); // HALF
228					while (f < ( f_count - 1 ) ) {
229						row_content = row_content + '▭'; // FULL
230						row_content_arr.push( 'F' ); // FULL
231						f++;
232					}
233					row_content = row_content + '◻'; // HALF
234					row_content_arr.push( 'H' ); // HALF
235				} else {
236					//console.log( 'EVEN:' );
237					while (f < f_count) {
238						row_content = row_content + '▭'; // FULL
239						row_content_arr.push( 'F' ); // FULL
240						f++;
241					}
242				}
243				row_content_arr.push( 'B' ); // BREAK
244			}
245			
246		}
247		
248		// Perform the calculation for Capping Blocks
249		// roundup(B14 / 0.456);
250		let capping_blocks_result = roundUp(adjustedLength / fullLength);
251		if ( mode == 'structure' ) { // We don't round up for Structures as we need to further alter the total number of capping blocks for these
252			capping_blocks_result = adjustedLength / fullLength;
253		}
254		console.log( 'capping_blocks_result: ' + capping_blocks_result );
255		
256		let c = 0;
257		let cap_content = '';
258		let cap_content_arr = [];
259		while (c < capping_blocks_result) {
260			cap_content = cap_content + '▱'; // C
261			cap_content_arr.push( 'C' ); // C
262			c++;
263		}
264		console.log( '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );
265		console.log( 'Block arrangement:' );
266		console.log( cap_content );
267		console.log( row_content );
268		console.log( '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );
269		//console.table( row_content_arr );
270		console.log( '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -' );
271		
272		/*if ( mode != 'structure' ) {
273			$( '#wall-preview-container' ).remove();
274			$( '.qb-results-inner' ).after( '<div id="wall-preview-container" style="border: 2px solid #000;padding:2rem;background-color:#eee;line-height:0;"></div>' );
275		}*/
276		
277		//renderWall( cap_content_arr, row_content_arr, mode );
278		
279		if ( mode != 'structure' ) {
280			
281			// Prepare Wall-only items:
282			$( '.c-height' ).addClass( 'border-right-none' );
283			$( '.c-width' ).addClass( 'hide' );
284			$( '.c-doors' ).addClass( 'hide' );
285			$( '.c-windows' ).addClass( 'hide' );
286			$( '#block_panel_results .quarter' ).addClass( 'hide' );
287
288			// Set result text
289			$( '#block_panel_results .full .num' ).text( fullCount );
290			$( '#block_panel_results .half .num' ).text( halfCount );
291			$( '#block_panel_results .quarter .num' ).text( '' ); // NOT USED FOR THIS SO WE SET TO EMPTY
292			$( '#block_panel_results .capping .num' ).text( capping_blocks_result );
293			$( '.qb-results-inner .measurements .length' ).text( ( adjustedLength / 1000 ) + ' m' );
294			$( '.qb-results-inner .measurements .width' ).text( '' );
295			$( '.qb-results-inner .measurements .height' ).text( ( adjustedHeight / 1000 ) + ' m' );
296			$( '.qb-results-inner .measurements .windows' ).text( '0' );
297			$( '.qb-results-inner .measurements .doors' ).text( '0' );
298
299			console.log( 'Rows: ' + rows );
300			console.log( 'Adjusted Wall Dimensions: ' + adjustedLength + 'mm x '  + adjustedHeight + 'mm' );
301			console.log( 'Full Blocks: ' + fullCount );
302			console.log( 'Half Blocks: ' + halfCount );
303
304			$( '#results' ).removeClass( 'hide' );
305			// Scroll to Results
306			$('html, body').animate({
307				scrollTop: $( '#qb_scroll_point_results' ).offset().top
308			}, 1000);
309		
310		}
311			
312		// Return the results
313		return {
314			adjustedLength,
315			adjustedHeight,
316			rows,
317			fullBlocks: fullCount,
318			halfBlocks: halfCount,
319			cappingBlocks: capping_blocks_result
320		};
321	}
322	
323	/*
324	 * CALCULATE STRUCTURE
325	 * 
326	 * - CALCULATE WINDOWS & DOORS
327	 * - We need to check if the length, width and height are big enough to allow door(s) and / or window(s) within.
328	 * - We do this by checking the entered dimensions and seeing if there is enough space to fit a door into it.
329	 * - DOORS:   2 x 9 blocks - 912mm x 2052mm
330	 * - WINDOWS: 1 x 2 blocks - 456mm x 456mm 
331	 * 
332	 * - Min width of wall to accommodate door 1824mm (2 x the width of the door)
333	 * - Calculation / logic: If wall width is less than 1824mm it is not possible to add a door, so door number field should be set to 0 and disabled.
334	 * 
335	 * - Min height of wall to accommodate door 2280mm (height of the door + 1 x block height)
336	 * - Calculation / logic: If wall height is less than 2280mm it is not possible to add a door, so the door number field should be set to 0 and disabled.
337	 * 
338	 * - Min width of window to accommodate window 1368mm (3 x the width of the window)
339	 * - Calculation / logic: If wall width is less than 1824mm then window number field should be set to 0 and disabled.
340	 * 
341	 * - Min height of window to accommodate window 912mm (2 x the height of the window, [4 x blocks tall])
342	 * - Calculation / logic: If wall height is less than 912mm then window number field should be set to 0 and disabled.
343	 */
344	
345	const doorHeight = 2052;
346	const doorWidth = 912;
347	const minDoorHeightThreshold = 2280; 
348	const minDoorWidthThreshold = 1824; // Amount of wall required for a single door in mm
349	const windowHeight = 456;
350	const windowWidth = 456;
351	const minWindowHeightThreshold = 912;
352	const minWindowWidthThreshold = 1368; // Amount of wall required for a single window in mm
353	let maxLengthDoors = 0;
354	let maxWidthDoors = 0;
355	let maxLengthWindows = 0;
356	let maxWidthWindows = 0;
357	let maxDoors = 0;
358	let maxWindows = 0;
359	let requiredDoors = 0;
360	let requiredWindows = 0;
361	let doorsHeightTooSmall = false;
362	let windowsHeightTooSmall = false;
363	
364	// These variables are used to track how much space is available 
365	// in each wall to allow doors or windows to be allocated.
366	let structureLengthWallAvailable1 = 0;
367	let structureLengthWallAvailable2 = 0;
368	let structureWidthWallAvailable1 = 0;
369	let structureWidthWallAvailable2 = 0;
370	
371	let result_warning = []; // This is used for any warning messages related to the final results
372	//let result_warning_items = '';
373	
374	function calculateMaxDoors( wallLength ) {
375		return Math.floor( wallLength / minDoorWidthThreshold );
376	}
377	
378	function calculateMaxWindows( wallLength ) {
379		return Math.floor( wallLength / minWindowWidthThreshold );
380	}
381	
382	function calculatePossibleDoorsWindows() {
383		var s_length = 0;
384		if ( $( '#s_length' ).val() != '' ) {
385			s_length = $( '#s_length' ).val();
386		}
387		
388		var s_height = 0;
389		if ( $( '#s_height' ).val() != '' ) {
390			s_height = $( '#s_height' ).val();
391		}
392		
393		var s_width = 0;
394		if ( $( '#s_width' ).val() != '' ) {
395			s_width = $( '#s_width' ).val();
396		}
397
398		s_length = parseFloat( s_length ) * 1000;
399		s_height = parseFloat( s_height ) * 1000;
400		s_width = parseFloat( s_width ) * 1000;
401		
402		console.log( 's_length: ' + s_length );
403		console.log( 's_width: ' + s_width );
404		console.log( 's_height: ' + s_height );
405		
406		// Round to the nearest multiples of block sizes
407		let adjustedStructureLength = Math.round(s_length / halfLength) * halfLength;
408		let adjustedStructureWidth = Math.round(s_width / halfLength) * halfLength;
409		let adjustedStructureHeight = Math.round(s_height / blockHeight) * blockHeight;
410		
411		// Set initial max available space per wall variables
412		structureLengthWallAvailable1 = adjustedStructureLength;
413		structureLengthWallAvailable2 = adjustedStructureLength;
414		structureWidthWallAvailable1 = adjustedStructureWidth;
415		structureWidthWallAvailable2 = adjustedStructureWidth;
416		
417		/*
418		 * THIS NEXT CODE CALCULATES POSSIBLE AMOUNT OF DOORS FOR THE WIDTH, HEIGHT, LENGTH
419		 * Note, this does not take into account any windows, just determines the max doors.
420		 */
421		// DOORS LENGTH
422		//$( '.msg-length' ).text( 'adjustedStructureLength: ' + adjustedStructureLength );
423		if ( adjustedStructureLength < minDoorWidthThreshold ) {
424			maxLengthDoors = 0;
425			//$( '.msg-length' ).text( 'Structure length too small to accommodate a door: Structure Length: ' + adjustedStructureLength + ' - Min Required Length: ' + minDoorWidthThreshold );
426		} else if ( adjustedStructureLength >= minDoorWidthThreshold ) {
427			maxLengthDoors = calculateMaxDoors( adjustedStructureLength );
428			//$( '.msg-length' ).text( 'Structure length can accommodate ' + maxLengthDoors + ' door(s): Structure Length: ' + adjustedStructureLength + ' - Min Required Length: ' + minDoorWidthThreshold );
429		}
430		
431		// DOORS WIDTH
432		//$( '.msg-width' ).text( 'adjustedStructureWidth: ' + adjustedStructureWidth );
433		if ( adjustedStructureWidth < minDoorWidthThreshold ) {
434			maxWidthDoors = 0;
435			//$( '.msg-width' ).text( 'Structure width too small to accommodate a door: Structure Width: ' + adjustedStructureWidth + ' - Min Required Width: ' + minDoorWidthThreshold );
436		} else if ( adjustedStructureWidth >= minDoorWidthThreshold ) {
437			maxWidthDoors = calculateMaxDoors( adjustedStructureWidth );
438			//$( '.msg-width' ).text( 'Structure width can accommodate ' + maxWidthDoors + ' door(s): Structure Width: ' + adjustedStructureWidth + ' - Min Required Width: ' + minDoorWidthThreshold );
439		}
440		
441		// DOORS HEIGHT
442		//$( '.msg-height' ).text( 'minDoorHeightThreshold: ' + minDoorHeightThreshold );
443		if ( adjustedStructureHeight < minDoorHeightThreshold ) {
444			//$( '.msg-height' ).text( 'Structure height too small to accommodate a door: Structure Height: ' + adjustedStructureHeight + ' - Min Required Height: ' + minDoorHeightThreshold );
445			maxLengthDoors = 0;
446			maxWidthDoors = 0;
447			doorsHeightTooSmall = true;
448			//$( '#s_doors' ).val( 0 ).attr( 'disabled', true );
449		} else if ( adjustedStructureHeight >= minDoorHeightThreshold ) {
450			doorsHeightTooSmall = false;
451			//maxWidthDoors = calculateMaxDoors( adjustedStructureWidth );
452			//$( '.msg-height' ).text( 'Structure height can accommodate a door: Structure Height: ' + adjustedStructureHeight + ' - Min Required Height: ' + minDoorHeightThreshold );
453			//$( '#s_doors' ).removeAttr( 'disabled' );
454		}
455		
456		// Set the maxDoors value. We have two of each wall so we need to multiply the value for each wall by 2 and add them together.
457		maxDoors = ( ( maxLengthDoors * 2 ) + ( maxWidthDoors * 2 ) );
458		
459		//$( '.msg-max-doors' ).text( maxDoors + ' max doors allowed.' );
460		
461		/*
462		 * THIS NEXT CODE CALCULATES POSSIBLE AMOUNT OF WINDOW FOR THE WIDTH, HEIGHT, LENGTH
463		 * Note, this does not take into account any doors, just determines the max windows.
464		 */
465		// WINDOWS LENGTH
466		//$( '.w-msg-length' ).text( 'adjustedStructureLength: ' + adjustedStructureLength );
467		if ( adjustedStructureLength < minWindowWidthThreshold ) {
468			maxLengthWindows = 0;
469			//$( '.w-msg-length' ).text( 'Structure length too small to accommodate a window: Structure Length: ' + adjustedStructureLength + ' - Min Required Length: ' + minWindowWidthThreshold );
470		} else if ( adjustedStructureLength >= minWindowWidthThreshold ) {
471			maxLengthWindows = calculateMaxWindows( adjustedStructureLength );
472			//$( '.w-msg-length' ).text( 'Structure length can accommodate ' + maxLengthWindows + ' window(s): Structure Length: ' + adjustedStructureLength + ' - Min Required Length: ' + minWindowWidthThreshold );
473		}
474		
475		// WINDOWS WIDTH
476		//$( '.w-msg-width' ).text( 'adjustedStructureWidth: ' + adjustedStructureWidth );
477		if ( adjustedStructureWidth < minWindowWidthThreshold ) {
478			maxWidthWindows = 0;
479			//$( '.w-msg-width' ).text( 'Structure width too small to accommodate a window: Structure Width: ' + adjustedStructureWidth + ' - Min Required Width: ' + minWindowWidthThreshold );
480		} else if ( adjustedStructureWidth >= minWindowWidthThreshold ) {
481			maxWidthWindows = calculateMaxWindows( adjustedStructureWidth );
482			//$( '.w-msg-width' ).text( 'Structure width can accommodate ' + maxWidthWindows + ' window(s): Structure Width: ' + adjustedStructureWidth + ' - Min Required Width: ' + minWindowWidthThreshold );
483		}
484		
485		// WINDOWS HEIGHT
486		//$( '.w-msg-height' ).text( 'minWindowHeightThreshold: ' + minWindowHeightThreshold );
487		if ( adjustedStructureHeight < minWindowHeightThreshold ) {
488			//$( '.w-msg-height' ).text( 'Structure height too small to accommodate a window: Structure Height: ' + adjustedStructureHeight + ' - Min Required Height: ' + minWindowHeightThreshold );
489			maxLengthWindows = 0;
490			maxWidthWindows = 0;
491			windowsHeightTooSmall = true;
492			//$( '#s_windows' ).val( 0 ).attr( 'disabled', true );
493		} else if ( adjustedStructureHeight >= minWindowHeightThreshold ) {
494			windowsHeightTooSmall = false;
495			//$( '.w-msg-height' ).text( 'Structure height can accommodate a window: Structure Height: ' + adjustedStructureHeight + ' - Min Required Height: ' + minWindowHeightThreshold );
496			//$( '#s_windows' ).removeAttr( 'disabled' );
497		}
498		
499		// Set the maxWindows value. We have two of each wall so we need to multiply the value for each wall by 2 and add them together.
500		maxWindows = ( ( maxLengthWindows * 2 ) + ( maxWidthWindows * 2 ) );
501		
502		console.log( 'maxDoors: ' + maxDoors );
503		console.log( 'maxWindows: ' + maxWindows );
504		
505		//$( '.w-msg-max-windows' ).text( maxWindows + ' max windows allowed.' );
506	}
507	
508	function renderResultWarning() {
509		let result_warning_items = '';
510		$( '.result-warning' ).html( '' ).hide();
511		if ( result_warning.length !== 0 ) {
512			console.log( '' );
513			console.log( 'Warnings exist' );
514			console.log( '' );
515			result_warning.forEach((item) => {
516				result_warning_items += '<li>' + item + '</li>';
517			});
518			$( '.result-warning' ).html( result_warning_items ).show();
519		} else {
520			console.log( '' );
521			console.log( 'NO Warnings exist' );
522			console.log( '' );
523			$( '.result-warning' ).html( '' ).hide();
524		}
525		
526		result_warning = [];
527	}
528	
529	function checkWallHeightWarning() {
530		let w_height = parseFloat( $( '#w_height' ).val() * 1000 );
531		if ( w_height > 2500 ) {
532			$( '#qb_wall .height-warning' ).show();
533			let w_warning_text = $( '#qb_wall .height-warning' ).text();
534			result_warning.push( w_warning_text );
535			//renderResultWarning();
536		} else {
537			$( '#qb_wall .height-warning' ).hide();
538			//renderResultWarning();
539		}
540	}
541	
542	function checkStructureHeightWarning() {
543		let s_height = parseFloat( $( '#s_height' ).val() * 1000 );
544		if ( s_height > 2500 ) {
545			$( '#qb_structure .height-warning' ).show();
546			let s_warning_text = $( '#qb_structure .height-warning' ).text();
547			result_warning.push( s_warning_text );
548			//renderResultWarning();
549		} else {
550			$( '#qb_structure .height-warning' ).hide();
551			//renderResultWarning();
552		}
553	}
554	
555	$( '#w_height, #w_length' ).keyup( function( event ) {
556		checkWallHeightWarning();
557		renderResultWarning();
558	});
559	
560	$( '#s_height, #s_length, #s_width' ).keyup( function( event ) {
561		checkStructureHeightWarning();
562		renderResultWarning();
563	});
564	
565	
566	
567	//function calculateAvailableSpaceForDoorsWindows() {
568	//	//maxLengthDoors
569	//	//maxWidthDoors
570	//	//maxLengthWindows
571	//	//maxWidthWindows
572	//	
573	//	//minDoorWidthThreshold = 1824
574	//	//minWindowWidthThreshold = 1368
575	//	
576	//	// Incrementing:
577	//	// maxDoors
578	//	// maxWindows
579	//	
580	//	var s_doors = 0;
581	//	if ( $( '#s_doors' ).val() != '' ) {
582	//		s_doors = parseFloat( $( '#s_doors' ).val() );
583	//	}
584	//	
585	//	var s_windows = 0;
586	//	if ( $( '#s_windows' ).val() != '' ) {
587	//		s_windows = parseFloat( $( '#s_windows' ).val() );
588	//	}
589	//	
590	//	if ( s_doors > 0 ) {
591	//		/* This calculation is explained as:
592	//		 * dimensions-of-length-wall EQUALS dimensions-of-length-wall MINUS ( length-of-blocks-needed-for-door MULTIPLIED BY number-of-doors )
593	//		 * structureLengthWallAvailable1 = ( structureLengthWallAvailable1 - ( minDoorWidthThreshold * s_doors ) );
594	//		 * e.g. 2964 - 1824 x 2 =
595	//		 * 2964 - 3648 = -684
596	//		 * 
597	//		 * As the amount of doors is increased we need to check if there is space to fit them in any of the walls,
598	//		 * if the first one has none, we try the second, and so on.
599	//		 * We also first check if the wall is big enough for a window in the first place by checking the `maxLengthDoors` and `maxWidthDoors` variables.
600	//		 * 
601	//		 */
602	//		
603	//		console.log( ' ' );
604	//		console.log( ' -  -  -  -  -  -  -  -  -' );
605	//		console.log( ' ' );
606	//		
607	//		if ( maxLengthDoors > 0 ) {
608	//			// We can test the Length Walls to see if there is room for doors
609	//			if ( ( structureLengthWallAvailable1 - ( minDoorWidthThreshold * s_doors ) < 0 ) ) {
610	//				// Length Wall 1 cannot fit any more doors
611	//				console.log( 'Length Wall 1 cannot fit any more doors' );
612	//			} else {
613	//				console.log( 'Length Wall 1 will fit doors' );
614	//			}
615	//			console.log( 'structureLengthWallAvailable1: ' + structureLengthWallAvailable1 );
616	//			console.log( 'minDoorWidthThreshold * s_doors : ' + minDoorWidthThreshold + ' X ' + s_doors + ' : ' + ( minDoorWidthThreshold * s_doors ) );
617	//			
618	//			if ( ( structureLengthWallAvailable2 - ( minDoorWidthThreshold * s_doors ) < 0 ) ) {
619	//				// Length Wall 2 cannot fit any more doors
620	//				console.log( 'Length Wall 2 cannot fit any more doors' );
621	//			} else {
622	//				console.log( 'Length Wall 2 will fit doors' );
623	//			}
624	//			
625	//			if ( ( structureWidthWallAvailable1 - ( minDoorWidthThreshold * s_doors ) < 0 ) ) {
626	//				// Width Wall 1 cannot fit any more doors
627	//				console.log( 'Width Wall 1 cannot fit any more doors' );
628	//			} else {
629	//				console.log( 'Width Wall 1 will fit doors' );
630	//			}
631	//			
632	//			if ( ( structureWidthWallAvailable2 - ( minDoorWidthThreshold * s_doors ) < 0 ) ) {
633	//				// Width Wall 2 cannot fit any more doors
634	//				console.log( 'Width Wall 2 cannot fit any more doors' );
635	//			} else {
636	//				console.log( 'Width Wall 2 will fit doors' );
637	//			}
638	//		}
639	//		
640	//		//structureLengthWallAvailable1 = ( structureLengthWallAvailable1 - ( minDoorWidthThreshold * s_doors ) );
641	//	}
642	//	
643	//	//if ( structureLengthWallAvailable1 ) {
644	//	//	
645	//	//}
646	//	
647	//	$( '.msg-door-window-calcs' ).text( '' );
648	//}
649	
650/*	// Door number field
651	$( '#s_doors' ).keyup( function( event ) {
652		var s_doors = 0;
653		if ( $( '#s_doors' ).val() != '' ) {
654			s_doors = parseFloat( $( '#s_doors' ).val() );
655			if ( s_doors <= maxDoors ) {
656				// Number of doors entered is less or equal to the maximum allowed
657				requiredDoors = s_doors;
658			} else {
659				// Number of doors entered is more than is allowed so we force it to the maximum allowed.
660				$( '#s_doors' ).val( requiredDoors );
661				requiredDoors = maxDoors;
662			}
663
664			//calculateAvailableSpaceForDoorsWindows();
665			
666		}
667	});
668	
669	// Window number field
670	$( '#s_windows' ).keyup( function( event ) {
671		var s_windows = 0;
672		if ( $( '#s_windows' ).val() != '' ) {
673			s_windows = parseFloat( $( '#s_windows' ).val() );
674			if ( s_windows <= maxWindows ) {
675				// Number of windows entered is less or equal to the maximum allowed
676				requiredWindows = s_windows;
677			} else {
678				// Number of windows entered is more than is allowed so we force it to the maximum allowed.
679				$( '#s_windows' ).val( requiredWindows );
680				requiredWindows = maxWindows;
681			}
682
683		}
684	});*/
685	
686	
687	function calculateStructureBlocks( structureHeight, structureLength, structureWidth, structureWindows, structureDoors ) {
688		// WE CALCULATE A STRUCTURE BY DOING EACH WALL INDIVIDUALLY
689		// GETTING THE RESULTING FULL, HALF AND CAPPING BLOCK AMOUNTS AND
690		// COMPENSATE FOR THE INTERLOCKING AT THE CORNERS OF THE STRUCTURE.
691		
692		console.log( 'structureHeight: ' + structureHeight );
693		console.log( 'structureLength: ' + structureLength );
694		console.log( 'structureWidth: ' + structureWidth );
695		console.log( 'structureWindows: ' + structureWindows );
696		console.log( 'structureDoors: ' + structureDoors );
697		
698		/*$( '#wall-preview-container' ).remove();
699		$( '.qb-results-inner' ).after( '<div id="wall-preview-container" style="border: 2px solid #000;padding:2rem;background-color:#eee;line-height:0;"></div>' );*/
700		
701		// GET ALL WALL SIZES SEPARATELY, TWO USING structureLength AND TWO USING structureWidth
702		const structureWallA = calculateWallBlocks( structureHeight, structureLength, 'structure' );
703		console.log( 'Wall A - adjustedLength: ' + structureWallA.adjustedLength );
704		console.log( 'Wall A - adjustedHeight: ' + structureWallA.adjustedHeight );
705		console.log( 'Wall A - Rows: ' + structureWallA.rows );
706		console.log( 'Wall A - Full Blocks: ' + structureWallA.fullBlocks );
707		console.log( 'Wall A - Half Blocks: ' + structureWallA.halfBlocks );
708		console.log( 'Wall A - Capping Blocks: ' + structureWallA.cappingBlocks );
709		
710		const structureWallB = calculateWallBlocks( structureHeight, structureLength, 'structure' );
711		console.log( 'Wall B - adjustedLength: ' + structureWallB.adjustedLength );
712		console.log( 'Wall B - adjustedHeight: ' + structureWallB.adjustedHeight );
713		console.log( 'Wall B - Rows: ' + structureWallB.rows );
714		console.log( 'Wall B - Full Blocks: ' + structureWallB.fullBlocks );
715		console.log( 'Wall B - Half Blocks: ' + structureWallB.halfBlocks );
716		console.log( 'Wall B - Capping Blocks: ' + structureWallB.cappingBlocks );
717		
718		const structureWallC = calculateWallBlocks( structureHeight, structureWidth, 'structure' );
719		console.log( 'Wall C - adjustedLength: ' + structureWallC.adjustedLength );
720		console.log( 'Wall C - adjustedHeight: ' + structureWallC.adjustedHeight );
721		console.log( 'Wall C - Rows: ' + structureWallC.rows );
722		console.log( 'Wall C - Full Blocks: ' + structureWallC.fullBlocks );
723		console.log( 'Wall C - Half Blocks: ' + structureWallC.halfBlocks );
724		console.log( 'Wall C - Capping Blocks: ' + structureWallC.cappingBlocks );
725		
726		const structureWallD = calculateWallBlocks( structureHeight, structureWidth, 'structure' );
727		console.log( 'Wall D - adjustedLength: ' + structureWallD.adjustedLength );
728		console.log( 'Wall D - adjustedHeight: ' + structureWallD.adjustedHeight );
729		console.log( 'Wall D - Rows: ' + structureWallD.rows );
730		console.log( 'Wall D - Full Blocks: ' + structureWallD.fullBlocks );
731		console.log( 'Wall D - Half Blocks: ' + structureWallD.halfBlocks );
732		console.log( 'Wall D - Capping Blocks: ' + structureWallD.cappingBlocks );
733		
734		let fullTotal = structureWallA.fullBlocks + structureWallB.fullBlocks + structureWallC.fullBlocks + structureWallD.fullBlocks;
735		let halfTotal = structureWallA.halfBlocks + structureWallB.halfBlocks + structureWallC.halfBlocks + structureWallD.halfBlocks;
736		halfTotal = 0; // We override halfBlocks to be 0, we will calculate these below if necessary when Doors and Windows are present
737		let capTotal = ( structureWallA.cappingBlocks + structureWallB.cappingBlocks + structureWallC.cappingBlocks + structureWallD.cappingBlocks ) - 2;
738		
739		let actualStructureLength = structureWallA.adjustedLength;
740		let actualStructureWidth  = structureWallC.adjustedLength;
741		let actualLengthInternal = round( actualStructureLength - fullLength, 2 );
742		let actualWidthInternal  = round( actualStructureWidth - fullLength, 2 );
743		let actualHeightRounded  = round( structureWallA.adjustedHeight, 2 );
744		
745		/* Adjust calculations to include any Doors / Windows...
746		 * It is a bit of a challenge to try and accommodate doors and windows,
747		 * first we check how many doors and / or windows there are, if both exist
748		 * then we need to see what combination of these is realistic, e.g. if
749		 * someone sets 9 doors and 9 windows this is probably too many, it is
750		 * unlikely someone wants 4 doors on a building, more likely they would
751		 * want 1 or 2 doors and also some windows. So how do we accommodate this?
752		 * 
753		 * One option is to try to accurately determine how many doors would fit into the space,
754		 * e.g. check the size of a wall, work out how many doors would fit into that space,
755		 * then do the same for windows and then we have a theoretical maximum of each. We then
756		 * try to use a more realistic variety of doors and windows based on those amounts. 
757		 *
758		 */
759		
760		calculatePossibleDoorsWindows();
761		
762		// Doors - Check if amount submitted needs adjusted
763		if ( structureDoors > maxDoors ) {
764			result_warning.push( 'You submitted ' + structureDoors + ' door(s), a maximum of ' + maxDoors + ' door(s) can be used for this structure.' );
765			structureDoors = maxDoors;
766		}
767		
768		// Windows - Check if amount submitted needs adjusted
769		if ( structureWindows > maxWindows ) {
770			result_warning.push( 'You submitted ' + structureWindows + ' window(s), a maximum of ' + maxWindows + ' window(s) can be used for this structure.' );
771			structureWindows = maxWindows;
772		}
773		
774		// structureLengthWallAvailable1
775		// structureLengthWallAvailable2
776		// structureWidthWallAvailable1
777		// structureWidthWallAvailable2
778		// are the available lengths of wall for each side of the structure.
779		
780		// We check if we can fit doors first of all, then once they are done we check if windows will fit in any of the remaining space.
781		// Loop over total amount of doors, but checking the maximum amount of doors per wall, until all doors are subtracted or space runs out
782
783		console.log( '' );
784		console.log( '-   -   -   -   -   -   -   -   -   -   -   -   -' );
785		console.log( 'DOORS' );
786		console.log( 'CHECKING IF DOORS FIT INTO AVAILABLE WALL LENGTHS...' );
787		console.log( 'Available space in wall lengths BEFORE Doors loop:' );
788		console.log( 'structureLengthWallAvailable1: ' + structureLengthWallAvailable1 );
789		console.log( 'structureLengthWallAvailable2: ' + structureLengthWallAvailable2 );
790		console.log( 'structureWidthWallAvailable1: ' + structureWidthWallAvailable1 );
791		console.log( 'structureWidthWallAvailable2: ' + structureWidthWallAvailable2 );
792		let d = 0;
793		let doors_added_count = 0;
794		while ( d < structureDoors ) {
795
796			if ( structureLengthWallAvailable1 >= minDoorWidthThreshold ) {
797				// There is room for a door in `structureLengthWallAvailable1`
798				console.log( 'There is room for a door in `structureLengthWallAvailable1`' );
799				structureLengthWallAvailable1 -= minDoorWidthThreshold;
800				doors_added_count++;
801				
802			} else {
803				// There is no more room for a door in `structureLengthWallAvailable1`
804				console.log( 'There is no more room for a door in `structureLengthWallAvailable1`' );
805				
806				if ( structureLengthWallAvailable2 >= minDoorWidthThreshold ) {
807					// There is room for a door in `structureLengthWallAvailable2`
808					console.log( 'There is room for a door in `structureLengthWallAvailable2`' );
809					structureLengthWallAvailable2 -= minDoorWidthThreshold;
810					doors_added_count++;
811					
812				} else {
813					// There is no more room for a door in `structureLengthWallAvailable2`
814					console.log( 'There is no more room for a door in `structureLengthWallAvailable2`' );
815					
816					if ( structureWidthWallAvailable1 >= minDoorWidthThreshold ) {
817						// There is room for a door in `structureWidthWallAvailable1`
818						console.log( 'There is room for a door in `structureWidthWallAvailable1`' );
819						structureWidthWallAvailable1 -= minDoorWidthThreshold;
820						doors_added_count++;
821						
822					} else {
823						// There is no more room for a door in `structureWidthWallAvailable1`
824						console.log( 'There is no more room for a door in `structureWidthWallAvailable1`' );
825						
826						if ( structureWidthWallAvailable2 >= minDoorWidthThreshold ) {
827							// There is room for a door in `structureWidthWallAvailable2`
828							console.log( 'There is room for a door in `structureWidthWallAvailable2`' );
829							structureWidthWallAvailable2 -= minDoorWidthThreshold;
830							doors_added_count++;
831							
832						} else {
833							// There is no more room for a door in `structureWidthWallAvailable2`
834							console.log( 'There is no more room for a door in `structureWidthWallAvailable2`' );
835
836						}
837					}
838				}
839			}
840			d++;
841		}
842		console.log( '' );
843		console.log( '-   -   -   -   -   -   -   -   -   -   -   -   -' );
844		console.log( 'doors_added_count: ' + doors_added_count );
845		console.log( 'Available space in wall lengths AFTER Doors loop:' );
846		console.log( 'structureLengthWallAvailable1: ' + structureLengthWallAvailable1 );
847		console.log( 'structureLengthWallAvailable2: ' + structureLengthWallAvailable2 );
848		console.log( 'structureWidthWallAvailable1: ' + structureWidthWallAvailable1 );
849		console.log( 'structureWidthWallAvailable2: ' + structureWidthWallAvailable2 );
850		console.log( '-   -   -   -   -   -   -   -   -   -   -   -   -' );
851		console.log( '' );
852
853		console.log( '' );
854		console.log( '-   -   -   -   -   -   -   -   -   -   -   -   -' );
855		console.log( 'WINDOWS' );
856		console.log( 'CHECKING IF WINDOWS FIT INTO AVAILABLE WALL LENGTHS...' );
857		console.log( 'Available space in wall lengths BEFORE Windows loop:' );
858		console.log( 'structureLengthWallAvailable1: ' + structureLengthWallAvailable1 );
859		console.log( 'structureLengthWallAvailable2: ' + structureLengthWallAvailable2 );
860		console.log( 'structureWidthWallAvailable1: ' + structureWidthWallAvailable1 );
861		console.log( 'structureWidthWallAvailable2: ' + structureWidthWallAvailable2 );
862		let w = 0;
863		let windows_added_count = 0;
864		while ( w < structureWindows ) {
865
866			if ( structureLengthWallAvailable1 >= minWindowWidthThreshold ) {
867				// There is room for a window in `structureLengthWallAvailable1`
868				console.log( 'There is room for a window in `structureLengthWallAvailable1`' );
869				structureLengthWallAvailable1 -= minWindowWidthThreshold;
870				windows_added_count++;
871				
872			} else {
873				// There is no more room for a window in `structureLengthWallAvailable1`
874				console.log( 'There is no more room for a window in `structureLengthWallAvailable1`' );
875				
876				if ( structureLengthWallAvailable2 >= minWindowWidthThreshold ) {
877					// There is room for a window in `structureLengthWallAvailable2`
878					console.log( 'There is room for a window in `structureLengthWallAvailable2`' );
879					structureLengthWallAvailable2 -= minWindowWidthThreshold;
880					windows_added_count++;
881					
882				} else {
883					// There is no more room for a window in `structureLengthWallAvailable2`
884					console.log( 'There is no more room for a window in `structureLengthWallAvailable2`' );
885					
886					if ( structureWidthWallAvailable1 >= minWindowWidthThreshold ) {
887						// There is room for a window in `structureWidthWallAvailable1`
888						console.log( 'There is room for a window in `structureWidthWallAvailable1`' );
889						structureWidthWallAvailable1 -= minWindowWidthThreshold;
890						windows_added_count++;
891						
892					} else {
893						// There is no more room for a window in `structureWidthWallAvailable1`
894						console.log( 'There is no more room for a window in `structureWidthWallAvailable1`' );
895						
896						if ( structureWidthWallAvailable2 >= minWindowWidthThreshold ) {
897							// There is room for a window in `structureWidthWallAvailable2`
898							console.log( 'There is room for a window in `structureWidthWallAvailable2`' );
899							structureWidthWallAvailable2 -= minWindowWidthThreshold;
900							windows_added_count++;
901							
902						} else {
903							// There is no more room for a window in `structureWidthWallAvailable2`
904							console.log( 'There is no more room for a window in `structureWidthWallAvailable2`' );
905
906						}
907					}
908				}
909			}
910			w++;
911		}
912		console.log( '' );
913		console.log( '-   -   -   -   -   -   -   -   -   -   -   -   -' );
914		console.log( 'windows_added_count: ' + windows_added_count );
915		console.log( 'Available space in wall lengths AFTER Windows loop:' );
916		console.log( 'structureLengthWallAvailable1: ' + structureLengthWallAvailable1 );
917		console.log( 'structureLengthWallAvailable2: ' + structureLengthWallAvailable2 );
918		console.log( 'structureWidthWallAvailable1: ' + structureWidthWallAvailable1 );
919		console.log( 'structureWidthWallAvailable2: ' + structureWidthWallAvailable2 );
920		console.log( '-   -   -   -   -   -   -   -   -   -   -   -   -' );
921		console.log( '' );
922		
923		
924		// doors_added_count
925		// windows_added_count
926		
927		// Doors - adjust block counts accordingly
928		if ( maxDoors > 0 && doorsHeightTooSmall == false ) {
929			let dac = 0;
930			while ( dac < doors_added_count ) {
931				fullTotal -= 18; // 1 door removes 18 full blocks
932				halfTotal += 8; // 1 door adds 8 half blocks
933				dac++;
934			}
935			
936		}
937		
938		// Windows - adjust block counts accordingly
939		if ( maxWindows > 0 && windowsHeightTooSmall == false ) {
940			let wac = 0;
941			while ( wac < windows_added_count ) {
942				fullTotal -= 2; // 1 window removes 2 full blocks
943				halfTotal += 2; // 1 window adds 2 half blocks
944				wac++;
945			}
946			
947		}
948		
949		if ( doors_added_count < structureDoors ) {
950			result_warning.push( '' + doors_added_count + ' of the ' + structureDoors + ' Doors you specified can fit into this structure. This may be due to the constraints of the dimensions of the structure you specified.' );
951		}
952		
953		if ( windows_added_count < structureWindows ) {
954			result_warning.push( '' + windows_added_count + ' of the ' + structureWindows + ' Windows you specified can fit into this structure. This may be due to the constraints of the dimensions of the structure you specified, and / or how many Doors you have specified.' );
955		}
956		
957		
958		// Update number of doors in Doors field
959		$( '#s_doors' ).val( doors_added_count );
960		
961		// Update number of windows in Windows field
962		$( '#s_windows' ).val( windows_added_count );
963		
964		/*if ( structureDoors == 1 && maxDoors > 0 && doorsHeightTooSmall == false ) {
965			// if we have only 1 door then this is fairly simple, we can adjust the `fullTotal` by the number of blocks for 1 door, and also add the half-blocks that are needed to the `halfTotal` value.
966			fullTotal = ( fullTotal - 18 ); // 1 door removes 18 full blocks
967			halfTotal = ( halfTotal + 8 ); // 1 door adds 8 half blocks
968		}
969
970		// Windows - adjust block counts accordingly
971		if ( structureWindows == 1 && maxWindows > 0 && windowsHeightTooSmall == false ) {
972			// if we have only 1 window then this is fairly simple, we can adjust the `fullTotal` by the number of blocks for 1 window, and also add the half-blocks that are needed to the `halfTotal` value.
973			fullTotal = ( fullTotal - 2 ); // 1 window removes 2 full blocks
974			halfTotal = ( halfTotal + 2 ); // 1 window adds 2 half blocks
975		}*/
976		
977		// IS STRUCTURE HEIGHT TOO SMALL FOR DOORS?
978		if ( doorsHeightTooSmall == true ) {
979			result_warning.push( 'The height of this structure is too small for door(s) to fit.' );
980		}
981		if ( windowsHeightTooSmall == true ) {
982			result_warning.push( 'The height of this structure is too small for window(s) to fit.' );
983		}
984		
985		// Render Capping Blocks as separate items
986		/*if ( $( '#wall-preview-container' ).length > 0 ) {
987			let c_char_count = 1;
988			while (c_char_count <= capTotal) {
989				let cap = '';
990				cap = '<div class="block cap" style="display:inline-block;width:40px;height:14px;background-color:#444;border:1px solid #fff;text-align:center;font-size:10px;line-height:1;padding-top:1px;padding-bottom:1px;color:#fff;">' + c_char_count + '</div>';
991				$( '#wall-preview-container' ).append( cap );
992				c_char_count++;
993			}
994		}*/
995		
996		// Prepare Structure-only items:
997		$( '.c-height' ).removeClass( 'border-right-none' );
998		$( '.c-width' ).removeClass( 'hide' );
999		$( '.c-doors' ).removeClass( 'hide' );
1000		$( '.c-windows' ).removeClass( 'hide' );
1001		
1002		// Set result text
1003		$( '#block_panel_results .full .num' ).text( fullTotal );
1004		$( '#block_panel_results .half .num' ).text( halfTotal );
1005		$( '#block_panel_results .capping .num' ).text( capTotal );
1006		$( '.qb-results-inner .measurements .length' ).text( ( actualStructureLength / 1000 )  + ' m' );
1007		$( '.qb-results-inner .measurements .width' ).text( ( actualStructureWidth / 1000 ) + ' m' );
1008		$( '.qb-results-inner .measurements .height' ).text( ( actualHeightRounded / 1000 ) + ' m' );
1009		//$( '.qb-results-inner .measurements .windows' ).text( structureWindows );
1010		//$( '.qb-results-inner .measurements .doors' ).text( structureDoors );
1011		$( '.qb-results-inner .measurements .windows' ).text( windows_added_count );
1012		$( '.qb-results-inner .measurements .doors' ).text( doors_added_count );
1013		
1014		$( '.qb-results-inner .internal-measurements .internal-length' ).text( ( actualLengthInternal / 1000 ) + 'm' );
1015		$( '.qb-results-inner .internal-measurements .internal-width' ).text( ( actualWidthInternal / 1000 ) + 'm' );
1016		$( '.qb-results-inner .internal-measurements .internal-height' ).text( ( actualHeightRounded / 1000 ) + 'm' );
1017		
1018		// Show any warnings for the results
1019		checkStructureHeightWarning(); // We check the structure height as there is an additional warning if height over 2.5m
1020		renderResultWarning();
1021		/*let result_warning_items = '';
1022		$( '.result-warning' ).html( '' ).hide();
1023		if ( result_warning.length !== 0 ) {
1024			console.log( '' );
1025			console.log( 'Warnings exist' );
1026			console.log( '' );
1027			result_warning.forEach((item) => {
1028				result_warning_items += '<li>' + item + '</li>';
1029			});
1030			$( '.result-warning' ).html( result_warning_items ).show();
1031		} else {
1032			console.log( '' );
1033			console.log( 'NO Warnings exist' );
1034			console.log( '' );
1035			$( '.result-warning' ).html( '' ).hide();
1036		}
1037		
1038		result_warning = [];*/
1039		
1040
1041		$( '#results' ).removeClass( 'hide' );
1042		// Scroll to Results
1043		$('html, body').animate({
1044			scrollTop: $( '#qb_scroll_point_results' ).offset().top
1045		}, 1000);
1046		
1047	}
1048
1049
1050	
1051	/*
1052	 * 
1053	 * ONE APPROACH FOR STRUCTURE CALCULATION (SUGGESTED BY ANDREW FROM QUICKBLOCK) IS TO TREAT ALL FOUR
1054	 * WALLS OF THE STRUCTURE AS IF THEY ARE JUST ONE BIG WIDE WALL. THE ADVANTAGE OF THIS APPROACH IS
1055	 * THAT WE ONLY NEED TO CALCULATE THE CORNER CONNECTION BLOCKS FOR ONE CORNER. SO WE COULD USE THE
1056	 * EXISTING WALL CALCULATION FUNCTION AND OFFSET THE RESULTING BLOCKS AS REQUIRED.
1057	 * 
1058	 * THE PROCESS FOR CALCUATING THIS WOULD BE:
1059	 * 
1060	 * - TAKE THE ENTERED `LENGTH` AND `WIDTH` VARIABLES, ADD THEM TOGETHER AND MULTIPLY BY TWO, E.G.
1061	 * 		• L: 1.82M, W: 1.82M
1062	 * 		• 1.8m + 1.8m = 3.6m
1063	 * 		• 3.6m x 2    = 7.2m
1064	 * 
1065	 * - WE THEN CALCULATE A WALL BASED ON THIS NEW COMBINED LENGTH AND THE SUPPLIED HEIGHT.
1066	 * - THIS GIVES A WALL USING THE FOLLOWING BLOCKS:
1067	 * 		• 124 FULL BLOCKS
1068	 * 		• 8 HALF BLOCKS
1069	 * 		• 16 CAPPING BLOCKS
1070	 * 
1071	 * - FOR A STRUCTURE WE NEED TO ADJUST FOR THE CORNER CONNECTIONS. WE DO THIS BY REMOVING ALL OF
1072	 *   THE HALF BLOCKS, THEN ADDING SOME ADDITIONAL FULL BLOCKS, THESE WILL BE HALF THE NUMBER OF
1073	 *   HALF BLOCKS, BASED ON THE ABOVE THIS GIVES US THE FOLLOWING RESULTS:
1074	 * 		- 8 HALF BLOCKS
1075	 * 		+ 4 FULL BLOCKS (8 DIVIDED BY 2)
1076	 * 		NEW RESULTS ARE: 
1077	 * 		• 128 FULL BLOCKS
1078	 * 		• 0 HALF BLOCKS
1079	 * 
1080	 * - WE ALSO NEED TO ADJUST THE CAPPING BLOCK AMOUNTS TO ADJUST FOR THE CORNERS. WE DO THIS BY
1081	 *   REMOVING TWO CAPPING BLOCKS, BASICALLY HALF A BLOCK PER CORNER:
1082	 * 		- 2 CAPPING BLOCKS
1083	 * 		NEW FULL RESULTS ARE:
1084	 * 		• 128 FULL BLOCKS
1085	 * 		• 0 HALF BLOCKS
1086	 * 		• 14 CAPPING BLOCKS
1087	 * 
1088	 * */
1089	
1090	
1091	$( 'body' ).on( 'click', '#qb_blockulator #button_wall', function( event ) {
1092		$( '#qb_wall' ).removeClass( 'hide' );
1093		$( '#qb_structure' ).addClass( 'hide' );
1094		$( '.internal-measurements .qb-column' ).addClass( 'hide' );
1095		$( '#results' ).addClass( 'hide' );
1096		
1097		$( '#button_wall' ).addClass( 'active' );
1098		$( '#button_structure' ).removeClass( 'active' );
1099		
1100		// Set Generate PDF button `mode` data attribute to `wall`
1101		$( '#generate_pdf' ).attr( 'data-mode', 'wall' );
1102		
1103		event.preventDefault();
1104	});
1105	
1106	$( 'body' ).on( 'click', '#qb_blockulator #button_structure', function( event ) {
1107		$( '#qb_structure' ).removeClass( 'hide' );
1108		$( '#qb_wall' ).addClass( 'hide' );
1109		$( '.internal-measurements .qb-column' ).removeClass( 'hide' );
1110		$( '#results' ).addClass( 'hide' );
1111		
1112		$( '#button_wall' ).removeClass( 'active' );
1113		$( '#button_structure' ).addClass( 'active' );
1114		
1115		// Set Generate PDF button `mode` data attribute to `structure`
1116		$( '#generate_pdf' ).attr( 'data-mode', 'structure' );
1117		
1118		event.preventDefault();
1119	});
1120	
1121	$( 'body' ).on( 'click', '#qb_blockulator #calculate_wall', function( event ) {
1122		let length = '';
1123		let height = '';
1124		if ( $( '#w_length' ).val() != '' ) {
1125			length = parseFloat( $( '#w_length' ).val() ) * 1000;
1126		}
1127		if ( $( '#w_height' ).val() != '' ) {
1128			height = parseFloat( $( '#w_height' ).val() ) * 1000;
1129		}
1130		
1131		console.log( 'height: ' + height );
1132		console.log( 'length: ' + length );
1133		
1134		$( '#w_length, #w_height' ).removeClass( 'alert' );
1135		
1136		if ( length != '' && height != '' ) {
1137			calculateWallBlocks( height, length, '' );
1138		}
1139		if ( length == '' ) {
1140			$( '#w_length' ).addClass( 'alert' );
1141		}
1142		if ( height == '' ) {
1143			$( '#w_height' ).addClass( 'alert' );
1144		}
1145		
1146		event.preventDefault();
1147	});
1148	
1149	$( 'body' ).on( 'click', '#qb_blockulator #calculate_structure', function( event ) {
1150		let width = '';
1151		let height = '';
1152		let length = '';
1153		if ( $( '#s_width' ).val() != '' ) {
1154			width = parseFloat( $( '#s_width' ).val() ) * 1000;
1155		}
1156		if ( $( '#s_height' ).val() != '' ) {
1157			height = parseFloat( $( '#s_height' ).val() ) * 1000;
1158		}
1159		if ( $( '#s_length' ).val() != '' ) {
1160			length = parseFloat( $( '#s_length' ).val() ) * 1000;
1161		}
1162		
1163		
1164		let windows = $( '#s_windows' ).val();
1165		let doors = $( '#s_doors' ).val();
1166		
1167		$( '#s_width, #s_height, #s_length' ).removeClass( 'alert' );
1168		
1169		console.log( 'width: ' + width );
1170		console.log( 'height: ' + height );
1171		console.log( 'length: ' + length );
1172		
1173		if ( width != '' && height != '' && length != '' ) {
1174			calculateStructureBlocks( height, length, width, windows, doors );
1175		}
1176		if ( width == '' ) {
1177			$( '#s_width' ).addClass( 'alert' );
1178		}
1179		if ( height == '' ) {
1180			$( '#s_height' ).addClass( 'alert' );
1181		}
1182		if ( length == '' ) {
1183			$( '#s_length' ).addClass( 'alert' );
1184		}
1185		
1186		event.preventDefault();
1187	});
1188	
1189	
1190	function generatePdfViaRest( data_mode, data_full_blocks, data_half_blocks, data_quarter_blocks, data_capping_blocks, data_desired_length, data_desired_height, data_desired_width, data_actual_length, data_actual_height, data_actual_width, data_actual_internal_length, data_actual_internal_width, data_windows, data_doors ) {
1191		console.log( 'Calling REST to generate PDF using `data_mode` - ' + data_mode );
1192		$( '#generate_pdf' ).addClass( 'loading' );
1193		// Send the data to the server using the REST API
1194		fetch(generatePDF.rest_url, {
1195			method: 'POST',
1196			headers: {
1197				'Content-Type': 'application/json',
1198				'X-WP-Nonce': generatePDF.nonce,
1199			},
1200			body: JSON.stringify({ 
1201				mode: data_mode,
1202				full_blocks: data_full_blocks,
1203				half_blocks: data_half_blocks,
1204				quarter_blocks: data_quarter_blocks,
1205				capping_blocks: data_capping_blocks,
1206				desired_length: data_desired_length,
1207				desired_height: data_desired_height,
1208				desired_width: data_desired_width, 
1209				actual_length: data_actual_length,
1210				actual_height: data_actual_height,
1211				actual_width: data_actual_width,
1212				actual_internal_length: data_actual_internal_length,
1213				actual_internal_width: data_actual_internal_width,
1214				windows: data_windows,
1215				doors: data_doors
1216			}),
1217		})
1218		.then((response) => response.json())
1219		.then((data) => {
1220			if (data.success) {
1221
1222				$( '#generate_pdf' ).removeClass( 'loading' );
1223				console.log( 'Data sent successfully');
1224				console.log( 'data.pdf_url: ' + data.pdf_url );
1225				console.log( 'data.pdf_filename: ' + data.pdf_filename );
1226				//console.log( 'data.nonce: ' + data.nonce );
1227				//console.log( 'Download URL: /wp-json/quickblock/v1/download-pdf?file_name=' + data.pdf_filename + '&nonce=' + data.nonce );
1228				const link = document.createElement( 'a' );
1229				//const download_url = '/wp-json/quickblock/v1/download-pdf?file_name=' + data.pdf_filename + '&nonce=' + data.nonce;
1230				link.href = data.pdf_url;
1231				//link.href = download_url;
1232				link.download = '' + data.pdf_filename + ''; // Filename for download
1233				link.click();
1234
1235			} else {
1236				$( '#generate_pdf' ).removeClass( 'loading' );
1237				console.log( 'Error sending generatePDF REST call.' );
1238			}
1239		})
1240		.catch((error) => {
1241			$( '#generate_pdf' ).removeClass( 'loading' );
1242			console.error('Error:', error);
1243			console.log( 'An error occurred with the generatePDF REST call.' );
1244		});
1245	}
1246	
1247	$( 'body' ).on( 'click', '#generate_pdf', function( event ) {
1248		console.log( 'Attempting to generate a PDF via a REST call...' );
1249		let mode = $( '#generate_pdf' ).attr( 'data-mode' );
1250		let full = $( '#block_panel_results .full .num' ).text();
1251		let half = $( '#block_panel_results .half .num' ).text();
1252		let quarter = $( '#block_panel_results .quarter .num' ).text();
1253		let capping = $( '#block_panel_results .capping .num' ).text();
1254		
1255		if ( mode == 'wall' ) {
1256			let desired_length = $( '#w_length' ).val();
1257			let desired_height = $( '#w_height' ).val();
1258			// desired_width N/A
1259			let actual_length = $( '#results .measurements .length' ).text();
1260			let actual_height = $( '#results .measurements .height' ).text();
1261			// actual_width N/A
1262			// windows N/A
1263			// doors N/A
1264			generatePdfViaRest( mode, full, half, '', capping, desired_length, desired_height, '', actual_length, actual_height, '', '', '', '', '' );
1265		}
1266		
1267		if ( mode == 'structure' ) {
1268			let desired_length = $( '#s_length' ).val();
1269			let desired_height = $( '#s_height' ).val();
1270			let desired_width  = $( '#s_width' ).val();
1271			let actual_length  = $( '#results .measurements .length' ).text();
1272			let actual_height  = $( '#results .measurements .height' ).text();
1273			let actual_width   = $( '#results .measurements .width' ).text();
1274			let actual_internal_length = $( '#results .internal-measurements .internal-length' ).text();
1275			let actual_internal_width  = $( '#results .internal-measurements .internal-width' ).text();
1276			let windows = $( '#results .measurements .windows' ).text();
1277			let doors   = $( '#results .measurements .doors' ).text();
1278			
1279			console.log( 'desired_length: ' + desired_length );
1280			console.log( 'desired_height: ' + desired_height );
1281			console.log( 'desired_width: ' + desired_width );
1282			console.log( 'actual_length: ' + actual_length );
1283			console.log( 'actual_height: ' + actual_height );
1284			console.log( 'actual_width: ' + actual_width );
1285			console.log( 'actual_internal_length: ' + actual_internal_length );
1286			console.log( 'actual_internal_width: ' + actual_internal_width );
1287			console.log( 'windows: ' + windows );
1288			console.log( 'doors: ' + doors );
1289			
1290			
1291			generatePdfViaRest( mode, full, half, quarter, capping, desired_length, desired_height, desired_width, actual_length, actual_height, actual_width, actual_internal_length, actual_internal_width, windows, doors );
1292		}
1293		
1294		event.preventDefault();
1295	});
1296
1297	
1298} )( jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.