<# if ( 'undefined' !== typeof FusionApp ) { #>
<# } else { #>
<# } #>
/*global fusionredux_change, wp, fusionredux, libFilter */ /** * Media Uploader * Dependencies : jquery, wp media uploader * Feature added by : Smartik - http://smartik.ws/ * Date : 05.28.2013 */ (function($){ "use strict"; fusionredux.field_objects = fusionredux.field_objects || {}; fusionredux.field_objects.media = fusionredux.field_objects.media || {}; var isFiltered; $( document ).ready( function() { } ); fusionredux.field_objects.media.init = function( selector ) { if ( !selector ) { selector = $( document ).find( ".fusionredux-group-tab:visible" ).find( '.fusionredux-container-media:visible' ); } $( selector ).each( function() { var el = $( this ); var parent = el; if ( !el.hasClass( 'fusionredux-field-container' ) ) { parent = el.parents( '.fusionredux-field-container:first' ); } if ( parent.is( ":hidden" ) ) { // Skip hidden fields return; } if ( parent.hasClass( 'fusionredux-field-init' ) ) { parent.removeClass( 'fusionredux-field-init' ); } else { return; } isFiltered = false; // Remove the image button el.find( '.remove-image, .remove-file' ).unbind( 'click' ).on( 'click', function() { fusionredux.field_objects.media.removeFile( $( this ).parents( 'fieldset.fusionredux-field:first' ) ); } ); // Upload media button el.find( '.media_upload_button' ).unbind().on( 'click', function( event ) { fusionredux.field_objects.media.addFile( event, $( this ).parents( 'fieldset.fusionredux-field:first' ) ); } ); } ); }; // Add a file via the wp.media function fusionredux.field_objects.media.addFile = function( event, selector ) { event.preventDefault(); var frame; var jQueryel = $( this ); var libFilter; // If the media frame already exists, reopen it. if ( frame ) { frame.open(); return; } // Get library filter data var filter = $( selector ).find('.library-filter').data('lib-filter'); // Must exist to do decoding if (filter !== undefined) { if (filter !== ''){ libFilter = []; isFiltered = true; filter = decodeURIComponent(filter); filter = JSON.parse(filter); $.each(filter, function(index, value) { libFilter.push(value); }); } } // Create the media frame. frame = wp.media( { multiple: false, library: { type: libFilter //Only allow images }, // Set the title of the modal. title: jQueryel.data( 'choose' ), // Customize the submit button. button: { // Set the text of the button. text: jQueryel.data( 'update' ) // Tell the button not to close the modal, since we're // going to refresh the page when the image is selected. } } ); // When an image is selected, run a callback. frame.on( 'select', function() { // Grab the selected attachment. var attachment = frame.state().get( 'selection' ).first(); frame.close(); var data = $( selector ).find('.data').data(); if ( typeof fusionredux.field_objects.media === 'undefined' || typeof fusionredux.field_objects.media === undefined ) { fusionredux.field_objects.media = {}; } if ( data === undefined || data.mode === 'undefined' ) { data = {}; data.mode = "image"; } if (isFiltered === true) { data.mode = 0; } if (data.mode === 0) { } else { if ( data.mode !== false) { if (attachment.attributes.type !== data.mode) { if (attachment.attributes.subtype !== data.mode ) { return; } } } } selector.find( '.upload' ).val( attachment.attributes.url ); selector.find( '.upload-id' ).val( attachment.attributes.id ); selector.find( '.upload-height' ).val( attachment.attributes.height ); selector.find( '.upload-width' ).val( attachment.attributes.width ); fusionredux_change( $( selector ).find( '.upload-id' ) ); var thumbSrc = attachment.attributes.url; if ( typeof attachment.attributes.sizes !== 'undefined' && typeof attachment.attributes.sizes.thumbnail !== 'undefined' ) { thumbSrc = attachment.attributes.sizes.thumbnail.url; } else if ( typeof attachment.attributes.sizes !== 'undefined' ) { var height = attachment.attributes.height; for ( var key in attachment.attributes.sizes ) { var object = attachment.attributes.sizes[key]; if ( object.height < height ) { height = object.height; thumbSrc = object.url; } } } else { thumbSrc = attachment.attributes.icon; } selector.find( '.upload-thumbnail' ).val( thumbSrc ); if ( !selector.find( '.upload' ).hasClass( 'noPreview' ) ) { selector.find( '.screenshot' ).empty().hide().append( '' ).slideDown( 'fast' ); } //selector.find('.media_upload_button').unbind(); selector.find( '.remove-image' ).removeClass( 'hide' );//show "Remove" button selector.find( '.fusionredux-background-properties' ).slideDown(); } ); // Finally, open the modal. frame.open(); }; // Function to remove the image on click. Still requires a save fusionredux.field_objects.media.removeFile = function( selector ) { // This shouldn't have been run... if ( !selector.find( '.remove-image' ).addClass( 'hide' ) ) { return; } selector.find( '.remove-image' ).addClass( 'hide' );//hide "Remove" button selector.find( '.upload' ).val( '' ); selector.find( '.upload-id' ).val( '' ); selector.find( '.upload-height' ).val( '' ); selector.find( '.upload-width' ).val( '' ); selector.find( '.upload-thumbnail' ).val( '' ); fusionredux_change( $( selector ).find( '.upload-id' ) ); selector.find( '.fusionredux-background-properties' ).hide(); var screenshot = selector.find( '.screenshot' ); // Hide the screenshot screenshot.slideUp(); selector.find( '.remove-file' ).unbind(); // We don't display the upload button if .upload-notice is present // This means the user doesn't have the WordPress 3.5 Media Library Support if ( selector.find( '.section-upload .upload-notice' ).length > 0 ) { selector.find( '.media_upload_button' ).remove(); } }; })( jQuery ); /*! elementor-pro - v3.18.0 - 06-12-2023 */ "use strict"; (self["webpackChunkelementor_pro"] = self["webpackChunkelementor_pro"] || []).push([["carousel"],{ /***/ "../modules/carousel/assets/js/frontend/handlers/base.js": /*!***************************************************************!*\ !*** ../modules/carousel/assets/js/frontend/handlers/base.js ***! \***************************************************************/ /***/ ((__unused_webpack_module, exports) => { Object.defineProperty(exports, "__esModule", ({ value: true })); exports["default"] = void 0; class CarouselBase extends elementorModules.frontend.handlers.SwiperBase { getDefaultSettings() { return { selectors: { swiperContainer: '.elementor-main-swiper', swiperSlide: '.swiper-slide' }, slidesPerView: { widescreen: 3, desktop: 3, laptop: 3, tablet_extra: 3, tablet: 2, mobile_extra: 2, mobile: 1 } }; } getDefaultElements() { const selectors = this.getSettings('selectors'), elements = { $swiperContainer: this.$element.find(selectors.swiperContainer) }; elements.$slides = elements.$swiperContainer.find(selectors.swiperSlide); return elements; } getEffect() { return this.getElementSettings('effect'); } getDeviceSlidesPerView(device) { const slidesPerViewKey = 'slides_per_view' + ('desktop' === device ? '' : '_' + device); return Math.min(this.getSlidesCount(), +this.getElementSettings(slidesPerViewKey) || this.getSettings('slidesPerView')[device]); } getSlidesPerView(device) { if ('slide' === this.getEffect()) { return this.getDeviceSlidesPerView(device); } return 1; } getDeviceSlidesToScroll(device) { const slidesToScrollKey = 'slides_to_scroll' + ('desktop' === device ? '' : '_' + device); return Math.min(this.getSlidesCount(), +this.getElementSettings(slidesToScrollKey) || 1); } getSlidesToScroll(device) { if ('slide' === this.getEffect()) { return this.getDeviceSlidesToScroll(device); } return 1; } getSpaceBetween(device) { let propertyName = 'space_between'; if (device && 'desktop' !== device) { propertyName += '_' + device; } return this.getElementSettings(propertyName).size || 0; } getSwiperOptions() { const elementSettings = this.getElementSettings(); const swiperOptions = { grabCursor: true, initialSlide: this.getInitialSlide(), slidesPerView: this.getSlidesPerView('desktop'), slidesPerGroup: this.getSlidesToScroll('desktop'), spaceBetween: this.getSpaceBetween(), loop: 'yes' === elementSettings.loop, speed: elementSettings.speed, effect: this.getEffect(), preventClicksPropagation: false, slideToClickedSlide: true, handleElementorBreakpoints: true }; if ('yes' === elementSettings.lazyload) { swiperOptions.lazy = { loadPrevNext: true, loadPrevNextAmount: 1 }; } if (elementSettings.show_arrows) { swiperOptions.navigation = { prevEl: '.elementor-swiper-button-prev', nextEl: '.elementor-swiper-button-next' }; } if (elementSettings.pagination) { swiperOptions.pagination = { el: '.swiper-pagination', type: elementSettings.pagination, clickable: true }; } if ('cube' !== this.getEffect()) { const breakpointsSettings = {}, breakpoints = elementorFrontend.config.responsive.activeBreakpoints; Object.keys(breakpoints).forEach(breakpointName => { breakpointsSettings[breakpoints[breakpointName].value] = { slidesPerView: this.getSlidesPerView(breakpointName), slidesPerGroup: this.getSlidesToScroll(breakpointName), spaceBetween: this.getSpaceBetween(breakpointName) }; }); swiperOptions.breakpoints = breakpointsSettings; } if (!this.isEdit && elementSettings.autoplay) { swiperOptions.autoplay = { delay: elementSettings.autoplay_speed, disableOnInteraction: !!elementSettings.pause_on_interaction }; } return swiperOptions; } getDeviceBreakpointValue(device) { if (!this.breakpointsDictionary) { const breakpoints = elementorFrontend.config.responsive.activeBreakpoints; this.breakpointsDictionary = {}; Object.keys(breakpoints).forEach(breakpointName => { this.breakpointsDictionary[breakpointName] = breakpoints[breakpointName].value; }); } return this.breakpointsDictionary[device]; } updateSpaceBetween(propertyName) { const deviceMatch = propertyName.match('space_between_(.*)'), device = deviceMatch ? deviceMatch[1] : 'desktop', newSpaceBetween = this.getSpaceBetween(device); if ('desktop' !== device) { this.swiper.params.breakpoints[this.getDeviceBreakpointValue(device)].spaceBetween = newSpaceBetween; } else { this.swiper.params.spaceBetween = newSpaceBetween; } this.swiper.params.spaceBetween = newSpaceBetween; this.swiper.update(); } async onInit() { elementorModules.frontend.handlers.Base.prototype.onInit.apply(this, arguments); if (1 >= this.getSlidesCount()) { return; } const Swiper = elementorFrontend.utils.swiper; this.swiper = await new Swiper(this.elements.$swiperContainer, this.getSwiperOptions()); const elementSettings = this.getElementSettings(); if ('yes' === elementSettings.pause_on_hover) { this.togglePauseOnHover(true); } // Expose the swiper instance in the frontend this.elements.$swiperContainer.data('swiper', this.swiper); } getChangeableProperties() { return { autoplay: 'autoplay', pause_on_hover: 'pauseOnHover', pause_on_interaction: 'disableOnInteraction', autoplay_speed: 'delay', speed: 'speed', width: 'width' }; } updateSwiperOption(propertyName) { if (0 === propertyName.indexOf('width')) { this.swiper.update(); return; } const elementSettings = this.getElementSettings(), newSettingValue = elementSettings[propertyName], changeableProperties = this.getChangeableProperties(); let propertyToUpdate = changeableProperties[propertyName], valueToUpdate = newSettingValue; // Handle special cases where the value to update is not the value that the Swiper library accepts switch (propertyName) { case 'autoplay': if (newSettingValue) { valueToUpdate = { delay: elementSettings.autoplay_speed, disableOnInteraction: 'yes' === elementSettings.pause_on_interaction }; } else { valueToUpdate = false; } break; case 'autoplay_speed': propertyToUpdate = 'autoplay'; valueToUpdate = { delay: newSettingValue, disableOnInteraction: 'yes' === elementSettings.pause_on_interaction }; break; case 'pause_on_hover': this.togglePauseOnHover('yes' === newSettingValue); break; case 'pause_on_interaction': valueToUpdate = 'yes' === newSettingValue; break; } // 'pause_on_hover' is implemented by the handler with event listeners, not the Swiper library if ('pause_on_hover' !== propertyName) { this.swiper.params[propertyToUpdate] = valueToUpdate; } this.swiper.update(); } onElementChange(propertyName) { if (1 >= this.getSlidesCount()) { return; } if (0 === propertyName.indexOf('width')) { this.swiper.update(); // If there is another thumbs slider, like in the Media Carousel widget. if (this.thumbsSwiper) { this.thumbsSwiper.update(); } return; } // This is for handling the responsive control 'space_between'. // Responsive controls require a separate way of handling, and some currently don't work // (Swiper bug, currently exists in v5.3.6) TODO: update Swiper when bug is fixed and handle responsive controls if (0 === propertyName.indexOf('space_between')) { this.updateSpaceBetween(propertyName); return; } const changeableProperties = this.getChangeableProperties(); if (Object.prototype.hasOwnProperty.call(changeableProperties, propertyName)) { this.updateSwiperOption(propertyName); } } onEditSettingsChange(propertyName) { if (1 >= this.getSlidesCount()) { return; } if ('activeItemIndex' === propertyName) { this.swiper.slideToLoop(this.getEditSettings('activeItemIndex') - 1); } } } exports["default"] = CarouselBase; /***/ }), /***/ "../modules/carousel/assets/js/frontend/handlers/testimonial-carousel.js": /*!*******************************************************************************!*\ !*** ../modules/carousel/assets/js/frontend/handlers/testimonial-carousel.js ***! \*******************************************************************************/ /***/ ((__unused_webpack_module, exports, __webpack_require__) => { var _interopRequireDefault = __webpack_require__(/*! @babel/runtime/helpers/interopRequireDefault */ "../node_modules/@babel/runtime/helpers/interopRequireDefault.js"); Object.defineProperty(exports, "__esModule", ({ value: true })); exports["default"] = void 0; var _base = _interopRequireDefault(__webpack_require__(/*! ./base */ "../modules/carousel/assets/js/frontend/handlers/base.js")); class TestimonialCarousel extends _base.default { getDefaultSettings() { const defaultSettings = super.getDefaultSettings(); defaultSettings.slidesPerView = { desktop: 1 }; Object.keys(elementorFrontend.config.responsive.activeBreakpoints).forEach(breakpointName => { defaultSettings.slidesPerView[breakpointName] = 1; }); if (defaultSettings.loop) { defaultSettings.loopedSlides = this.getSlidesCount(); } return defaultSettings; } getEffect() { return 'slide'; } } exports["default"] = TestimonialCarousel; /***/ }) }]); //# sourceMappingURL=carousel.998a291abf70435fd698.bundle.js.map What Causes Building Projects to Go Wrong

What Causes Building Projects to Go Wrong? Delays, Overruns, and Broken Promises:

What Causes Building Projects to Go Wrong? “Six weeks to completion” somehow stretches into six months. The budget increases by 40% through mysterious “unforeseen circumstances.” That dream kitchen starts resembling a compromise at best. These scenarios play out with alarming frequency in home renovations, leaving homeowners wondering how projects that begin with such promise so often derail.

Understanding the root causes of construction failures provides homeowners with the knowledge to prevent them. Let’s examine the most common factors that send building projects spiralling and how to address them proactively.

Inadequate Planning and Preparation

Rushing into construction without thorough planning creates a perfect environment for failure. Comprehensive planning requires time—measuring precisely, considering all systems (plumbing, electrical, HVAC), and anticipating potential obstacles. Homeowners eager to see progress often push to start demolition before designs are finalized, creating a cascade of on-the-fly decisions that lead to inconsistencies and compromises.

Prevention: Allow adequate time for detailed planning. Complete all design decisions before work begins. Hire an architect or designer for complex projects to create comprehensive documentation that leaves little to interpretation.

Unrealistic Budgeting

Many projects begin with fundamentally unrealistic budgets, often based on television renovation shows that don’t reflect real costs, outdated pricing information, or simply wishful thinking. When the true costs emerge, corners get cut, inferior materials substitute for quality ones, and finger-pointing begins.

Prevention: Research current material and labour costs thoroughly. Include a 15-20% contingency fund for unexpected issues. Get detailed, itemized quotes that specify exact materials and labour hours. Remember that quality renovations represent a long-term investment, not a place for aggressive cost-cutting.

Poor Communication

Communication breakdowns cause countless construction disputes. Assumptions replace clarity, verbal agreements supersede written documentation, and critical details get lost in casual conversations. When multiple subcontractors enter the mix without clear direction, coordination problems multiply.

Prevention: Document every decision in writing. Establish regular meeting schedules and communication protocols. Create a single point of contact for decision-making and maintain a shared document repository for plans, changes, and progress reports.

Inadequate Project Management

Even with excellent plans and materials, poor day-to-day management derails projects. Scheduling dependencies require careful orchestration—plumbers must complete rough-in work before drywall installation, which must finish before painting can begin. When this sequence breaks down, delays and rework become inevitable.

Prevention: Ensure your builder uses professional project management systems and has dedicated management personnel for your project. Request detailed timeline charts showing dependencies and critical path activities. Verify they have systems for coordinating subcontractors and deliveries.

Scope Creep

The innocent-sounding “while we’re at it” phrase has doomed many timelines and budgets. Adding features or changing decisions mid-project disrupts workflow, requires reworking completed elements, and creates cascading delays through the schedule. What seems like a simple addition often affects multiple interconnected systems.

Prevention: Finalize all design decisions before construction begins. If changes become necessary, understand their full impact on timeline and budget before approving them. Document all changes with formal change orders that detail cost and schedule implications.

Substandard Workmanship

Quality craftsmanship requires skill, experience, and pride in one’s work—attributes not universal among those swinging hammers. When builders hire the cheapest available labour or rush to meet unrealistic deadlines, craftsmanship suffers. Problems may not appear immediately, but eventually manifest as crooked tiles, sticking doors, or failing systems.

Prevention: Research your builder’s reputation thoroughly. Visit their current job sites unannounced to observe workmanship and site management. Establish quality standards in your contract and inspect work at key milestones before making progress payments.

Weather and External Factors

Some project challenges genuinely lie beyond anyone’s control. Weather delays exterior work, supply chain disruptions affect material availability, and inspection departments operate on their own schedules. These factors impact even the best-managed projects.

Prevention: Build weather contingencies into outdoor project schedules. Order critical materials well in advance of need dates. Maintain good relationships with inspectors by ensuring work exceeds minimum code requirements.

Insufficient Details in Contracts

Vague contracts create fertile ground for disagreements. Terms like “high-quality fixtures” or “premium finishes” mean different things to different people. Without specific product selections, allowance amounts, and quality standards, disappointment becomes almost inevitable.

Prevention: Include brand names, model numbers, and allowance amounts for all fixtures and finishes. Specify construction methods and material grades. Leave nothing to interpretation—if it matters to you, document it in the contract.

The difference between renovation success and failure often comes down to preparation, communication, and vigilance. By understanding these common pitfalls and implementing preventive measures, homeowners can dramatically improve their chances of bringing their vision to life without the delays, overruns, and disappointments that plague so many building projects.

Thinking about transforming your home?

Get your free personalised AI renovation plan in 60 seconds.

Get My Free Plan →

Free — no obligation — plan ready in 60 seconds

Scroll to Top