} }, methods: { init : function( options ) { var settings = $.extend(true, {}, defaults); settings.options = $.extend(true, settings.options, options); var $siblingElements = this; var uniqueForms = $.unique( $siblingElements.map( function () { return $(this).parents("form")[0]; }).toArray() ); $(uniqueForms).bind("submit", function (e) { var $form = $(this); var warningsFound = 0; var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); $inputs.trigger("submit.validation").trigger("validationLostFocus.validation"); $inputs.each(function (i, el) { var $this = $(el), $controlGroup = $this.parents(".form-group").first(); if ( $controlGroup.hasClass("warning") ) { $controlGroup.removeClass("warning").addClass("error"); warningsFound++; } }); $inputs.trigger("validationLostFocus.validation"); if (warningsFound) { if (settings.options.preventSubmit) { e.preventDefault(); } $form.addClass("error"); if ($.isFunction(settings.options.submitError)) { settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true)); } } else { $form.removeClass("error"); if ($.isFunction(settings.options.submitSuccess)) { settings.options.submitSuccess($form, e); } } }); return this.each(function(){ // Get references to everything we're interested in var $this = $(this), $controlGroup = $this.parents(".form-group").first(), $helpBlock = $controlGroup.find(".help-block").first(), $form = $this.parents("form").first(), validatorNames = []; // create message container if not exists if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { $helpBlock = $('
'); $controlGroup.find('.controls').append($helpBlock); createdElements.push($helpBlock[0]); } // ============================================================= // SNIFF HTML FOR VALIDATORS // ============================================================= // *snort sniff snuffle* if (settings.options.sniffHtml) { var message = ""; // --------------------------------------------------------- // PATTERN // --------------------------------------------------------- if ($this.attr("pattern") !== undefined) { message = "Not in the expected format"; if ($this.data("validationPatternMessage")) { message = $this.data("validationPatternMessage"); } $this.data("validationPatternMessage", message); $this.data("validationPatternRegex", $this.attr("pattern")); } // --------------------------------------------------------- // MAX // --------------------------------------------------------- if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); message = "Too high: Maximum of '" + max + "'"; if ($this.data("validationMaxMessage")) { message = $this.data("validationMaxMessage"); } $this.data("validationMaxMessage", message); $this.data("validationMaxMax", max); } // --------------------------------------------------------- // MIN // --------------------------------------------------------- if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); message = "Too low: Minimum of '" + min + "'"; if ($this.data("validationMinMessage")) { message = $this.data("validationMinMessage"); } $this.data("validationMinMessage", message); $this.data("validationMinMin", min); } // --------------------------------------------------------- // MAXLENGTH // --------------------------------------------------------- if ($this.attr("maxlength") !== undefined) { message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters"; if ($this.data("validationMaxlengthMessage")) { message = $this.data("validationMaxlengthMessage"); } $this.data("validationMaxlengthMessage", message); $this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); } // --------------------------------------------------------- // MINLENGTH // --------------------------------------------------------- if ($this.attr("minlength") !== undefined) { message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters"; if ($this.data("validationMinlengthMessage")) { message = $this.data("validationMinlengthMessage"); } $this.data("validationMinlengthMessage", message); $this.data("validationMinlengthMinlength", $this.attr("minlength")); } // --------------------------------------------------------- // REQUIRED // --------------------------------------------------------- if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { message = settings.builtInValidators.required.message; if ($this.data("validationRequiredMessage")) { message = $this.data("validationRequiredMessage"); } $this.data("validationRequiredMessage", message); } // --------------------------------------------------------- // NUMBER // --------------------------------------------------------- if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { message = settings.builtInValidators.number.message; if ($this.data("validationNumberMessage")) { message = $this.data("validationNumberMessage"); } $this.data("validationNumberMessage", message); } // --------------------------------------------------------- // EMAIL // --------------------------------------------------------- if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { message = "Not a valid email address"; if ($this.data("validationValidemailMessage")) { message = $this.data("validationValidemailMessage"); } else if ($this.data("validationEmailMessage")) { message = $this.data("validationEmailMessage"); } $this.data("validationValidemailMessage", message); } // --------------------------------------------------------- // MINCHECKED // --------------------------------------------------------- if ($this.attr("minchecked") !== undefined) { message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required"; if ($this.data("validationMincheckedMessage")) { message = $this.data("validationMincheckedMessage"); } $this.data("validationMincheckedMessage", message); $this.data("validationMincheckedMinchecked", $this.attr("minchecked")); } // --------------------------------------------------------- // MAXCHECKED // --------------------------------------------------------- if ($this.attr("maxchecked") !== undefined) { message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required"; if ($this.data("validationMaxcheckedMessage")) { message = $this.data("validationMaxcheckedMessage"); } $this.data("validationMaxcheckedMessage", message); $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); } } // ============================================================= // COLLECT VALIDATOR NAMES // ============================================================= // Get named validators if ($this.data("validation") !== undefined) { validatorNames = $this.data("validation").split(","); } // Get extra ones defined on the element's data attributes $.each($this.data(), function (i, el) { var parts = i.replace(/([A-Z])/g, ",$1").split(","); if (parts[0] === "validation" && parts[1]) { validatorNames.push(parts[1]); } }); // ============================================================= // NORMALISE VALIDATOR NAMES // ============================================================= var validatorNamesToInspect = validatorNames; var newValidatorNamesToInspect = []; do // repeatedly expand 'shortcut' validators into their real validators { // Uppercase only the first letter of each name $.each(validatorNames, function (i, el) { validatorNames[i] = formatValidatorName(el); }); // Remove duplicate validator names validatorNames = $.unique(validatorNames); // Pull out the new validator names from each shortcut newValidatorNamesToInspect = []; $.each(validatorNamesToInspect, function(i, el) { if ($this.data("validation" + el + "Shortcut") !== undefined) { // Are these custom validators? // Pull them out! $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) { newValidatorNamesToInspect.push(el2); }); } else if (settings.builtInValidators[el.toLowerCase()]) { // Is this a recognised built-in? // Pull it out! var validator = settings.builtInValidators[el.toLowerCase()]; if (validator.type.toLowerCase() === "shortcut") { $.each(validator.shortcut.split(","), function (i, el) { el = formatValidatorName(el); newValidatorNamesToInspect.push(el); validatorNames.push(el); }); } } }); validatorNamesToInspect = newValidatorNamesToInspect; } while (validatorNamesToInspect.length > 0) // ============================================================= // SET UP VALIDATOR ARRAYS // ============================================================= var validators = {}; $.each(validatorNames, function (i, el) { // Set up the 'override' message var message = $this.data("validation" + el + "Message"); var hasOverrideMessage = (message !== undefined); var foundValidator = false; message = ( message ? message : "'" + el + "' validation failed " ) ; $.each( settings.validatorTypes, function (validatorType, validatorTemplate) { if (validators[validatorType] === undefined) { validators[validatorType] = []; } if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { validators[validatorType].push( $.extend( true, { name: formatValidatorName(validatorTemplate.name), message: message }, validatorTemplate.init($this, el) ) ); foundValidator = true; } } ); if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); if (hasOverrideMessage) { validator.message = message; } var validatorType = validator.type.toLowerCase(); if (validatorType === "shortcut") { foundValidator = true; } else { $.each( settings.validatorTypes, function (validatorTemplateType, validatorTemplate) { if (validators[validatorTemplateType] === undefined) { validators[validatorTemplateType] = []; } if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]); validators[validatorType].push( $.extend( validator, validatorTemplate.init($this, el) ) ); foundValidator = true; } } ); } } if (! foundValidator) { $.error("Cannot find validation info for '" + el + "'"); } }); // ============================================================= // STORE FALLBACK VALUES // ============================================================= $helpBlock.data( "original-contents", ( $helpBlock.data("original-contents") ? $helpBlock.data("original-contents") : $helpBlock.html() ) ); $helpBlock.data( "original-role", ( $helpBlock.data("original-role") ? $helpBlock.data("original-role") : $helpBlock.attr("role") ) ); $controlGroup.data( "original-classes", ( $controlGroup.data("original-clases") ? $controlGroup.data("original-classes") : $controlGroup.attr("class") ) ); $this.data( "original-aria-invalid", ( $this.data("original-aria-invalid") ? $this.data("original-aria-invalid") : $this.attr("aria-invalid") ) ); // ============================================================= // VALIDATION // ============================================================= $this.bind( "validation.validation", function (event, params) { var value = getValue($this); // Get a list of the errors to apply var errorsFound = []; $.each(validators, function (validatorType, validatorTypeArray) { if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) { $.each(validatorTypeArray, function (i, validator) { if (settings.validatorTypes[validatorType].validate($this, value, validator)) { errorsFound.push(validator.message); } }); } }); return errorsFound; } ); $this.bind( "getValidators.validation", function () { return validators; } ); // ============================================================= // WATCH FOR CHANGES // ============================================================= $this.bind( "submit.validation", function () { return $this.triggerHandler("change.validation", {submitting: true}); } ); $this.bind( [ "keyup", "focus", "blur", "click", "keydown", "keypress", "change" ].join(".validation ") + ".validation", function (e, params) { var value = getValue($this); var errorsFound = []; $controlGroup.find("input,textarea,select").each(function (i, el) { var oldCount = errorsFound.length; $.each($(el).triggerHandler("validation.validation", params), function (j, message) { errorsFound.push(message); }); if (errorsFound.length > oldCount) { $(el).attr("aria-invalid", "true"); } else { var original = $this.data("original-aria-invalid"); $(el).attr("aria-invalid", (original !== undefined ? original : false)); } }); $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); errorsFound = $.unique(errorsFound.sort()); // Were there any errors? if (errorsFound.length) { // Better flag it up as a warning. $controlGroup.removeClass("success error").addClass("warning"); // How many errors did we find? if (settings.options.semanticallyStrict && errorsFound.length === 1) { // Only one? Being strict? Just output it. $helpBlock.html(errorsFound[0] + ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); } else { // Multiple? Being sloppy? Glue them together into an UL. $helpBlock.html("" + ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); } } else { $controlGroup.removeClass("warning error success"); if (value.length > 0) { $controlGroup.addClass("success"); } $helpBlock.html($helpBlock.data("original-contents")); } if (e.type === "blur") { $controlGroup.removeClass("success"); } } ); $this.bind("validationLostFocus.validation", function () { $controlGroup.removeClass("success"); }); }); }, destroy : function( ) { return this.each( function() { var $this = $(this), $controlGroup = $this.parents(".form-group").first(), $helpBlock = $controlGroup.find(".help-block").first(); // remove our events $this.unbind('.validation'); // events are namespaced. // reset help text $helpBlock.html($helpBlock.data("original-contents")); // reset classes $controlGroup.attr("class", $controlGroup.data("original-classes")); // reset aria $this.attr("aria-invalid", $this.data("original-aria-invalid")); // reset role $helpBlock.attr("role", $this.data("original-role")); // remove all elements we created if (createdElements.indexOf($helpBlock[0]) > -1) { $helpBlock.remove(); } } ); }, collectErrors : function(includeEmpty) { var errorMessages = {}; this.each(function (i, el) { var $el = $(el); var name = $el.attr("name"); var errors = $el.triggerHandler("validation.validation", {includeEmpty: true}); errorMessages[name] = $.extend(true, errors, errorMessages[name]); }); $.each(errorMessages, function (i, el) { if (el.length === 0) { delete errorMessages[i]; } }); return errorMessages; }, hasErrors: function() { var errorMessages = []; this.each(function (i, el) { errorMessages = errorMessages.concat( $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : [] ); }); return (errorMessages.length > 0); }, override : function (newDefaults) { defaults = $.extend(true, defaults, newDefaults); } }, validatorTypes: { callback: { name: "callback", init: function ($this, name) { return { validatorName: name, callback: $this.data("validation" + name + "Callback"), lastValue: $this.val(), lastValid: true, lastFinished: true }; }, validate: function ($this, value, validator) { if (validator.lastValue === value && validator.lastFinished) { return !validator.lastValid; } if (validator.lastFinished === true) { validator.lastValue = value; validator.lastValid = true; validator.lastFinished = false; var rrjqbvValidator = validator; var rrjqbvThis = $this; executeFunctionByName( validator.callback, window, $this, value, function (data) { if (rrjqbvValidator.lastValue === data.value) { rrjqbvValidator.lastValid = data.valid; if (data.message) { rrjqbvValidator.message = data.message; } rrjqbvValidator.lastFinished = true; rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message); // Timeout is set to avoid problems with the events being considered 'already fired' setTimeout(function () { rrjqbvThis.trigger("change.validation"); }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst } } ); } return false; } }, ajax: { name: "ajax", init: function ($this, name) { return { validatorName: name, url: $this.data("validation" + name + "Ajax"), lastValue: $this.val(), lastValid: true, lastFinished: true }; }, validate: function ($this, value, validator) { if (""+validator.lastValue === ""+value && validator.lastFinished === true) { return validator.lastValid === false; } if (validator.lastFinished === true) { validator.lastValue = value; validator.lastValid = true; validator.lastFinished = false; $.ajax({ url: validator.url, data: "value=" + value + "&field=" + $this.attr("name"), dataType: "json", success: function (data) { if (""+validator.lastValue === ""+data.value) { validator.lastValid = !!(data.valid); if (data.message) { validator.message = data.message; } validator.lastFinished = true; $this.data("validation" + validator.validatorName + "Message", validator.message); // Timeout is set to avoid problems with the events being considered 'already fired' setTimeout(function () { $this.trigger("change.validation"); }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst } }, failure: function () { validator.lastValid = true; validator.message = "ajax call failed"; validator.lastFinished = true; $this.data("validation" + validator.validatorName + "Message", validator.message); // Timeout is set to avoid problems with the events being considered 'already fired' setTimeout(function () { $this.trigger("change.validation"); }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst } }); } return false; } }, regex: { name: "regex", init: function ($this, name) { return {regex: regexFromString($this.data("validation" + name + "Regex"))}; }, validate: function ($this, value, validator) { return (!validator.regex.test(value) && ! validator.negative) || (validator.regex.test(value) && validator.negative); } }, required: { name: "required", init: function ($this, name) { return {}; }, validate: function ($this, value, validator) { return !!(value.length === 0 && ! validator.negative) || !!(value.length > 0 && validator.negative); }, blockSubmit: true }, match: { name: "match", init: function ($this, name) { var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first(); element.bind("validation.validation", function () { $this.trigger("change.validation", {submitting: true}); }); return {"element": element}; }, validate: function ($this, value, validator) { return (value !== validator.element.val() && ! validator.negative) || (value === validator.element.val() && validator.negative); }, blockSubmit: true }, max: { name: "max", init: function ($this, name) { return {max: $this.data("validation" + name + "Max")}; }, validate: function ($this, value, validator) { return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative) || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); } }, min: { name: "min", init: function ($this, name) { return {min: $this.data("validation" + name + "Min")}; }, validate: function ($this, value, validator) { return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative) || (parseFloat(value) >= parseFloat(validator.min) && validator.negative); } }, maxlength: { name: "maxlength", init: function ($this, name) { return {maxlength: $this.data("validation" + name + "Maxlength")}; }, validate: function ($this, value, validator) { return ((value.length > validator.maxlength) && ! validator.negative) || ((value.length <= validator.maxlength) && validator.negative); } }, minlength: { name: "minlength", init: function ($this, name) { return {minlength: $this.data("validation" + name + "Minlength")}; }, validate: function ($this, value, validator) { return ((value.length < validator.minlength) && ! validator.negative) || ((value.length >= validator.minlength) && validator.negative); } }, maxchecked: { name: "maxchecked", init: function ($this, name) { var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); elements.bind("click.validation", function () { $this.trigger("change.validation", {includeEmpty: true}); }); return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements}; }, validate: function ($this, value, validator) { return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative) || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); }, blockSubmit: true }, minchecked: { name: "minchecked", init: function ($this, name) { var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); elements.bind("click.validation", function () { $this.trigger("change.validation", {includeEmpty: true}); }); return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements}; }, validate: function ($this, value, validator) { return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative) || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); }, blockSubmit: true } }, builtInValidators: { email: { name: "Email", type: "shortcut", shortcut: "validemail" }, validemail: { name: "Validemail", type: "regex", regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}", message: "Not a valid email address" }, passwordagain: { name: "Passwordagain", type: "match", match: "password", message: "Does not match the given password" }, positive: { name: "Positive", type: "shortcut", shortcut: "number,positivenumber" }, negative: { name: "Negative", type: "shortcut", shortcut: "number,negativenumber" }, number: { name: "Number", type: "regex", regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?", message: "Must be a number" }, integer: { name: "Integer", type: "regex", regex: "[+-]?\\\d+", message: "No decimal places allowed" }, positivenumber: { name: "Positivenumber", type: "min", min: 0, message: "Must be a positive number" }, negativenumber: { name: "Negativenumber", type: "max", max: 0, message: "Must be a negative number" }, required: { name: "Required", type: "required", message: "This is required" }, checkone: { name: "Checkone", type: "minchecked", minchecked: 1, message: "Check at least one option" } } }; var formatValidatorName = function (name) { return name .toLowerCase() .replace( /(^|\s)([a-z])/g , function(m,p1,p2) { return p1+p2.toUpperCase(); } ) ; }; var getValue = function ($this) { // Extract the value we're talking about var value = $this.val(); var type = $this.attr("type"); if (type === "checkbox") { value = ($this.is(":checked") ? value : ""); } if (type === "radio") { value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : ""); } return value; }; function regexFromString(inputstring) { return new RegExp("^" + inputstring + "$"); } /** * Thanks to Jason Bunting via StackOverflow.com * * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910 * Short link: http://tinyurl.com/executeFunctionByName **/ function executeFunctionByName(functionName, context /*, args*/) { var args = Array.prototype.slice.call(arguments).splice(2); var namespaces = functionName.split("."); var func = namespaces.pop(); for(var i = 0; i < namespaces.length; i++) { context = context[namespaces[i]]; } return context[func].apply(this, args); } $.fn.jqBootstrapValidation = function( method ) { if ( defaults.methods[method] ) { return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { return defaults.methods.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' ); return null; } }; $.jqBootstrapValidation = function (options) { $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments); }; })( jQuery ); //Unified: 02js.cookie-2.2.0.min.js /*! js-cookie v2.2.0 | MIT */ !function(e){var n=!1;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var o=window.Cookies,t=window.Cookies=e();t.noConflict=function(){return window.Cookies=o,t}}}(function(){function e(){for(var e=0,n={};e1){if("number"==typeof(i=e({path:"/"},t.defaults,i)).expires){var a=new Date;a.setMilliseconds(a.getMilliseconds()+864e5*i.expires),i.expires=a}i.expires=i.expires?i.expires.toUTCString():"";try{c=JSON.stringify(r),/^[\{\[]/.test(c)&&(r=c)}catch(e){}r=o.write?o.write(r,n):encodeURIComponent(r+"").replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=(n=(n=encodeURIComponent(n+"")).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent)).replace(/[\(\)]/g,escape);var s="";for(var f in i)i[f]&&(s+="; "+f,!0!==i[f]&&(s+="="+i[f]));return document.cookie=n+"="+r+s}n||(c={});for(var p=document.cookie?document.cookie.split("; "):[],d=/(%[0-9A-Z]{2})+/g,u=0;u' + blurb + '
' ); } }); //Unified: main.js jQuery(document).ready(function ($) { // Fires whenever a player has finished loading function onFancyboxPlayerReady(event) { //event.target.playVideo(); //console.log(jQuery(event.target)); } // Fires when the player's state changes. function onFancyboxPlayerStateChange(event) { //console.log(event.target.getCurrentTime());//getID (href is undefined) //console.log("playerStateChange: "+event.data); // Send Analytics event when video completes if (event.data === 0) { typeof ga == "undefined" ? console.log("ga:completeVideo:" + ytVidId(event.target.getVideoUrl())) : ga( "gtag_UA_78785039_1.send", "event", "Video", "complete", ytVidId(event.target.getVideoUrl()), 1 ); //$.fancybox.close(); } } // Add fancybox for homepagebanner's 'Watch Video' button var $allAtags = $("a"); if ($allAtags.length) { // do we have a match? $allAtags.each(function (index) { var href = $(this).attr("href"); if (href && ytVidId(href)) { let theIframe, id // check if youtube url is valid console.log("[Tam] attaching fancybox for: " + href); $(this).fancybox({ afterLoad: function (instance, current) { //console.log(jQuery(instance)); //console.log(jQuery(current)); // Find the iframe ID //console.log(instance.current.$slide.find('iframe'));//alternate find theIframe = instance.$refs.container.find("iframe"); id = theIframe.attr("id"); //console.log('fancy box afterLoad, found:',{theIframe,id}); }, onActivate: function (instance, current) { if (typeof YT == "undefined" || typeof YT.Player == "undefined") { setTimeout(() => { var tag = document.createElement("script"); tag.src = "https://www.youtube.com/iframe_api"; tag.async = true; var firstScriptTag = document.getElementsByTagName("script")[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); }, 100) } setTimeout(() => { // Create video player object and add event listeners var player = new YT.Player(id, { host: 'https://www.youtube-nocookie.com', playerVars: { origin: window.location.host }, events: { onReady: onFancyboxPlayerReady, onStateChange: onFancyboxPlayerStateChange } }); }, 1500) typeof ga == "undefined" ? console.log("ga:playVideo:" + ytVidId(href)) : ga( "gtag_UA_78785039_1.send", "event", "Video", "start", ytVidId(href), 1 ); } }); // initialize fancybox } else if (href && href.indexOf(".pdf") != -1) { $(this).fancybox({ onActivate: function () { typeof ga == "undefined" ? console.log("ga:clickPDF: " + href) : ga("gtag_UA_78785039_1.send", "event", "PDF", "click", href, 1); } }); } }); } var $allfancyboxelements = $(".fancyboxme"); if ($allfancyboxelements.length) { // do we have a match? $allfancyboxelements.each(function (index) { var href = $(this).attr("href") || $(this); console.log("[Tam] .fancyboxme for: " + href); $(this).fancybox(); // initialize fancybox }); } $("#shiftnav-toggle-main-button").click(function () { $(".shiftnav-active > .shiftnav-submenu-activation-close").trigger( "mouseup" ); $("#shiftnav-main").scrollTop(0); }); }); /** * JavaScript function to match (and return) the video Id * of any valid Youtube Url, given as input string. * @author: Stephan Schmitz * @url: http://stackoverflow.com/a/10315969/624466 */ function ytVidId(url) { var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/; return url.match(p) ? RegExp.$1 : false; } //Unified: search.js jQuery(document).on('submit','form.searchform',function(){ jQuery('.search-icon').addClass('fa fa-spinner fa-pulse').removeClass('et-icon-search et-icon'); }); jQuery(document).ready(function() { jQuery(document).click(function(evt){ console.log("2do - close if the target of the click != search field"); if(!jQuery(evt.target).is(jQuery("#search-icon #s")) && !jQuery(evt.target).is(jQuery("#search-icon .et-icon-search"))) { searchClose(); } }); jQuery("#search-icon #s").focus( function(){ jQuery(this).select(); jQuery("#search-icon #s").keypress(function(){ jQuery("#search-icon #s").unbind(); jQuery(document).keydown(function(e){ if (e.keyCode == 27) { // escape key maps to keycode `27` searchClose(); jQuery("#search-icon #s").unbind(); } }); }); console.log(jQuery(this)); } ); jQuery(".tam_search_animate_width").click(searchOpen); jQuery(".tam_search_animate_width").mouseover(searchOpen); }); function searchOpen(){ if(jQuery('.tam_search_animate_width').siblings('.content-box').first().width()<1){ jQuery('#search-icon').css("color","#3e3e3e"); jQuery('.tam_search_animate_width').siblings('.content-box').first().animate( { width: jQuery('.tam_search_animate_width').siblings('.content-box'). first().children().first().outerWidth()+"px"}, 600, function(){ jQuery("#search-icon #s").select(); jQuery("#search-icon .et-icon-search").click(function() { jQuery('form.searchform').submit(); }); } ); } jQuery("#search-icon #s").focus(); // jQuery('i.fa-search').addClass('fa-search-plus').removeClass('fa-search'); jQuery(".tam_search_animate_width").unbind(); //jQuery("#search-icon .tam_search_animate_width").unbind(); } function searchClose(){ jQuery('.tam_search_animate_width').siblings('.content-box').first().animate( {width: "0px"}, 400 ); jQuery('#search-icon').css("color","#FFF"); jQuery("#search-icon .et-icon-search").unbind(); jQuery(".tam_search_animate_width").click(searchOpen); jQuery(".tam_search_animate_width").mouseover(searchOpen); } //Unified: sign-up.js /* moved to code modules in the footer... jQuery(document).ready(function ($) { // Add fancybox for newsletter button var $allAtags = $('.popup-newsletter, .popup-newsletter a'); if ($allAtags.length) { // do we have a match? $allAtags.each(function(index){ //var href = $( this ).attr('href'); //console.log("[Tam] attaching newsletter fancybox for: "+href); $( this ).fancybox({ onActivate: function(){(typeof ga == 'undefined') ? console.log('ga:openNewsletter') : ga('gtag_UA_78785039_1.send', 'event', 'Form', 'open', 'Newsletter - Sign Up', 1);} }); // initialize fancybox }); } //$('#popup-newsletter-scrolltop').hide(); setTimeout(function() { // console.log(window.location.hash+" 600){ jQuery('#popup-newsletter-scrolltop').show(); } },2500); $('.close-button').click(function() { // console.log('closing?'); $(this).parent().hide(); //2do write cookie that expires in one week Cookies.set('signup', 'temp', { expires: 7 }); }); }); */ //Unified: stackfix.js //stackfix code //just add stackfix as a class to a full width element (with a unique id) //and it will stick when it scrolls off the top jQuery(document).ready( function() { var stackArray = {}; var stackCount=0; var currentStackHeight=0; var lastWindowScrollTop=jQuery(window).scrollTop(); jQuery(document).on("scroll", function(e) { var delta=jQuery(window).scrollTop() - lastWindowScrollTop; lastWindowScrollTop=jQuery(window).scrollTop(); if (delta > 0 ) {// jQuery(this).offset().top - ( currentStackHeight + 1 ) ) { var ph = jQuery('
').addClass('stackfix_placeholder').css('height', jQuery(this).outerHeight()); jQuery(this).after(ph); jQuery(this).detach().appendTo('#stackfix-container'); stackArray[this.id]={ scrollTop:jQuery(this).offset().top, oldPrevSib:jQuery(this).prev()[0], placeHolder:ph[0] }; stackCount++; currentStackHeight+=jQuery(this).outerHeight(); }//0){//2do // console.log("2do - animate scrollfix on screen"); // } }//

O Novo Paradigma da Água

Restauração Global do Clima e Ecossistemas

Bernd Walter Mueller, editado por Helena Laughton, em Julho de 2016

Download PDF

O Novo Paradigma da Água é um paradigma de gestão natural da água. Ele resulta num Plano de Acção Global para a Restauração Regenerativa dos Ecossistemas e do Clima, descrito por Michal Kravčík e envolve a mobilização de milhões de pessoas em centenas de milhares de projectos de gestão descentralizada da água espalhados por todo o mundo. Estes diversos projectos têm todos o objectivo de restaurar e fazer um melhor uso dos ciclos naturais da água em prol da restauração regenerativa dos ecossistemas.

A maioria das crises globais relacionadas com a água, tais como: escassez de água, secas, desertificação, inundações, aumento do nível do mar e alterações climáticas são sintomas de uma prolongada gestão danosa das águas pluviais e da vegetação. Isto resulta na perturbação dos ciclos hidrológicos naturais. Tentar responder a esta problemática com métodos industriais de controlo e mitigação não é uma solução viável. Estes métodos desprovidos de sustentabilidade podem ser substituídos pelo Novo Paradigma da Água, que apoia o Plano de Acção Global (PAG). Este plano global propõe uma resposta holística que aborda simultaneamente todos estes problemas.

Um elemento importante do PAG é o design abrangente e integrativo das Paisagens de Retenção de Água, que são implementadas como modelos holísticos à escala das bacias hidrográficas regionais. Os movimentos populares de restauração podem atrair apoio e inspiração destes projectos modelo, o que resultará na difusão de um movimento descentralizado em crescente expansão mundial. Assim sendo, a restauração global é alcançada através da acção local.

Implementar o Novo Paradigma da Água tem três resultados interligados:

Restauração Regenerativa de Ecossistemas

Restauração Climática

Regeneração Social

Restauração de Ecossistemas Regenerativos

A abundância ao nível de água e alimento pode ser realidade para todos os habitantes da Terra, caso os princípios da gestão natural de água forem compreendidos e implementados.

Esta compreensão e a sua implementação conduzirá ao restauro do ecossistema mundial.

Os princípios cruciais da gestão natural da água são:

descentralização da gestão da água

prevenção de escoamento desnecessário de água, recorrendo à infiltração de águas pluviais no corpo terrestre

replantação abundante das bacias hidrográficas.

Restaurar os ciclos hidrológicos naturais só será possível através de actividades localizadas e descentralizadas. Para que as pessoas se tornem responsáveis e actuem com seriedade de forma a restaurar os seus ecossistemas locais, temos de examinar a gestão da água primeiramente ao nível de cada bacia hidrográfica. Os movimentos descentralizados têm ciclos de feedback curtos e eficazes, que permitem que as pessoas observem e sintam os efeitos das suas próprias acções. O cidadão comum fica assim capacitado para restaurar as paisagens que habita, observando como uma gestão responsável da água beneficia a sua própria vida. Seguindo os princípios do Novo Paradigma da Água, a gestão descentralizada da Água activa também a re-diversificação da agricultura regional. Projectos centralizados de grande escala não oferecem as mesmas vantagens.

Actualmente, os ciclos hidrológicos naturais encontram-se danificados no mundo inteiro. A água da chuva não consegue infiltrar-se no solo devido à erosão e à má gestão da vegetação. Isso é causado principalmente por práticas agrícolas industriais e pela ampla impermeabilização das superfícies urbanas. O escoamento da água da chuva priva os ecossistemas da água necessária e seca-os progressivamente. Os reservas de água subterrânea esgotam-se e as nascentes secam, acelerando o processo de desertificação. Os padrões de precipitação tornam-se mais extremos e provocam danos às infraestruturas, poluição nos rios e inundações. Desta forma, os ecossistemas são destruídos, a gravidade dos eventos hídricos aumenta e a agricultura torna-se cada vez mais difícil.

Para reverter essa situação, o primeiro passo é implementar medidas de retenção de água da chuva que permitam que a água se infiltre no corpo terrestre e que a vegetação aumente novamente, regenerando o solo superficial. Os ciclos hidrológicos naturais são um pré-requisito para restaurar ecossistemas intactos e, assim, desenvolver uma agricultura regenerativa.

Num ecossistema com ciclos hidrológicos naturais intactos, grande parte da terra é sombreada e permeada por raízes de vegetação diversa. Uma camada fértil de solo superficial, protegida pela vegetação densa, absorve a maior parte da água da chuva. A partir daí, a água da chuva infiltra-se lentamente no solo, recarregando aquíferos que ressurgem como água de nascente mineralizada e vitalizada. O corpo terrestre serve de amortecedor, absorvendo até as chuvas fortes. Quando os aquíferos estão saturados, a água está disponível em fontes e poços, mesmo durante a estação seca. Os rios compostos por água de nascente, que flui constantemente, serpenteiam pela terra e fluem até ao mar.

Restauro do Clima

A gestão natural da água não é apenas um factor chave para a restauração regenerativa de ecossistemas, mas, de forma ainda mais radical, é também crucial para a restauração do clima. Mudanças destrutivas do clima, incluindo o aquecimento global do qual resultam as catástrofes naturais, como furacões, são normalmente atribuídas ao aumento das emissões de gases de efeito de estufa. Também é verdade, contudo, que a desertificação e destruição dos ciclos naturais da água são os maiores contribuidores para as alterações climáticas. Com a restauração dos ciclos hidrológicos naturais, podemos restaurar o clima para condições benéficas. Isto significa que podemos almejar muito mais que a simples adaptação às alterações climáticas – podemos apontar para uma verdadeiro restauração do clima.

Existem três exemplos claros da correlação entre a gestão natural de água e a restauração do clima:

a correlação entre a queda dos níveis de água nos aquíferos e a subida do nível do mar

fixação de carbono pela vegetação

papel do vapor de água no balanço energético

A actividade humana actual diminui sistematicamente a infiltração de águas pluviais no solo. Assim, flui mais quantidade de água dos continentes para os oceanos do que é transferida do oceano para a terra como chuva. Neste processo, a terra perde água continuamente, secando. Isto conduz, por um lado, à descida no nível dos aquíferos, ao nível continental e, por outro, ao aumento do nível do mar. Num ecossistema intacto com ciclos hidrológicos naturais equilibrados, parte da água das chuvas é usada pela vegetação e outra parte evapora novamente. Mas a maioria da água é absorvida pelo corpo terrestre. Nestas condições, o equilíbrio é mantido entre a água que flui dos continentes para os oceanos e a água que é transferida dos oceanos para a terra em forma de chuva. Os aquíferos permanecem, por isso, estáveis. O corpo terrestre tem suficiente capacidade de armazenamento de água para evitar que a água das chuvas saia da terra e contribua para a subida do nível do mar.

A restauração dos ciclos hidrológicos naturais está intrinsecamente ligada ao crescimento da cobertura de vegetação. Isto resulta no armazenamento de grandes quantidades de carbono na vegetação visível e em extensos sistemas radiculares no corpo terrestre. Sendo o carbono um dos gases de efeito estufa mais importantes, isto conduz à reversão das emissões de carbono. A reversão das emissões de carbono é, assim, um efeito colateral da restauração de ecossistemas, de acordo com o Novo Paradigma da Água.

Num ecossistema intacto, bastante água evapora e evapotranspira da vegetação para a atmosfera. A evaporação da água é um processo que consome energia e, assim, arrefece a crosta terrestre. Esse movimento da água, da crosta terrestre até à atmosfera, é um processo termorregulador que mantém as temperaturas adequadas à vida na Terra. Nas áreas urbanas, onde a superfície é impermeabilizada, em paisagens desertificadas e noutros ecossistemas danificados com alto escoamento de águas pluviais, esse processo é interrompido. Os ciclos naturais de evaporação e evapotranspiração, que dependem do solo e da vegetação, deixam de funcionar. Então, a energia que antes era usada na evaporação aquece directamente a Terra, contribuindo significativamente para o aquecimento global.

Regeneração Social

A restauração do ecossistema e do clima através da gestão natural de água oferece muitas oportunidades para a regeneração social:

emprego e educação relevantes

renovação cultural

melhoria das condições de vida.

Implementar projectos de Gestão Integrada das bacias hidrográficas em concordância com o Novo Paradigma da Água requer muita mão-de-obra. Isto proporciona milhões de empregos de médio e longo prazo, e é uma oportunidade sem precedentes para uma educação holística que beneficia tanto a sociedade como o planeta. Isto pode oferecer aos jovens adultos, educação em design ecológico e oportunidades para a sua aplicação prática. Quando os jovens têm este tipo de abundância de trabalho relevante, eles beneficiam de um sentido de propósito, sendo capacitados para desempenhar um papel válido ao serviço da comunidade.

A Gestão Integrada da Bacia Hidrográfica inclui uma reapreciação do papel da água na paisagem cultural.

Envolve reconexão com a bacia hidrográfica local e com a comunidade humana local. Catalisa o renovado interesse nas tradições locais de honrar e celebrar nascentes e rios.

Isso fortalece a cooperação entre os habitantes das bacias hidrográficas que assumem a responsabilidade pelos ecossistemas que habitam. Como tal, é uma oportunidade para construir novas redes comunitárias através de uma tarefa e propósito compartilhados, com base no Novo Paradigma da Água. A cooperação com a natureza torna-se um valor comum, e as pessoas reconhecem a responsabilidade que têm pelo bem-estar das futuras gerações.

Em todo o mundo, os padrões de vida são melhorados quando as pessoas têm acesso fácil a água de qualidade. A restauração do ecossistema reduz a ameaça de eventos hídricos extremos e melhora as condições agrícolas. Isso melhora a vida de milhões de pessoas, tanto no hemisfério sul como no hemisfério norte.

Garantir a abundância de água através da gestão descentralizada leva a uma maior resiliência comunitária. Isso ajuda a proteger as condições de vida, mesmo em tempos de crise.

Conclusão

O Novo Paradigma da Água e o Plano de Acção Global para a Restauração Regenerativa de Ecossistemas e do Clima (PAG) oferecem uma resposta holística a diversas crises globais da actualidade, relacionadas com o tema da água. A implementação deste paradigma, em modelos holísticos e em movimentos generalizados, tem um efeito profundo e rápido no bem-estar da vida na Terra.

Casos de Estudo de Restauro Regenerativo de Ecossistemas

Existem muitos exemplos da implementação do Novo Paradigma da Água na Gestão Natural da Água.

Para uma discussão mais aprofundada sobre a ligação entre a Gestão Natural da Água e a restauração do clima, ver “Água para a Recuperação do Clima: Um Novo Paradigma da Água” (Inglês), por M. Kravčík, J. Pokorny, J. Kohutiar, M. Kovac e E. Toth.

Aqueles que desejam implementar o plano PAG são encorajados a estudar os métodos, descobertas e sucessos dos seguintes projectos e teorias:

“People and Water” [“Pessoas e Água”] (Eslováquia)

Restauração de Ecossistemas e o Novo Paradigma da Água
ludiaavoda.sk
theflowpartnership.org/people-and-water

Projecto de Reabilitação do Planalto de Loess (China)

Reabilitação de Grande-escala da Bacia Hidrográfica
eempc.org/loess-plateau-watershed-rehabilitation-project (Inglês)

The Savory Institute (globalmente)

Gestão Holística
savory.global

Tamera, Biótopo de Cura 1 (Alentejo, Portugal)

Design de Paisagens de Retenção de Água
Instituto de Ecologia Global
Relatório sobre a Apresentação do Novo Paradigma da Água na COP22 em Marrocos (Inglês)

Tarun Barat Sangh (Rajasthan, India)

Design de Paisagens de Retenção de Água de grande escala
tarunbharatsangh.in

TreePeople (Los Angeles, U.S.A.)

Retenção Urbana de Águas Pluviais e Restauração de Ecossistemas
treepeople.org

Yeomans’ Keyline Plan (worldwide)

Restauração dos Solos e Agricultura Regenerativa
permaculturenews.org/2013/02/22/before-permaculture-keyline-planning-and-cultivation (Inglês)
soilandhealth.org/wp-content/uploads/01aglibrary/010125yeomans/010125toc.html (Inglês)

www.tamera.org