!function(){"use strict";var a={version:"3.2.0"};if("object"==typeof module&&"object"==typeof module.exports?module.exports=a:"function"==typeof define&&define.amd&&define(a),"undefined"!=typeof window){var b=window.W3W;a.noConflict=function(){return window.W3W=b,this},window.W3W=a}a.Xhr={getXhr:function(){if(window.XMLHttpRequest)return window.XMLHttpRequest;if(window.ActiveXObject)try{return new ActiveXObject("MSxml2.XMLHTTP")}catch(a){try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(b){return!1}}return!1},handleRequest:function(a,b,c,d){var e=new XMLHttpRequest;c=c?c:"GET",e.open(c,a,!0),e.onreadystatechange=function(a){var c;4==e.readyState&&(200==e.status?(c=JSON.parse(e.responseText),c.hasOwnProperty("error")&&b.onFailure?b.onFailure(c):b.onSuccess&&b.onSuccess(c)):b.onFailure&&(c=JSON.parse(e.responseText),b.onFailure(c)))},d?(e.setRequestHeader("Content-Length",d.length),e.send(d)):e.send()}},a.Utils={mergeOptions:function(a){var b,c,d,e,f=JSON.parse(JSON.stringify(a));for(b=1,d=arguments.length;b<d;b++){e=arguments[b];for(c in e)f[c]=e[c]}return f},assembleQuery:function(a){var b=[];for(var c in a)b.push(c+"="+encodeURIComponent(a[c]));return b.join("&")}},a.Geocoder=function(b){if(this.base_url="https://api.what3words.com/v2/","undefined"==typeof b)throw new Error("Missing what3words options");if(b&&!b.hasOwnProperty("key"))throw new Error("Missing what3words API key");this.options={lang:"en",format:"json"},this.options=a.Utils.mergeOptions(this.options,b),this.options.hasOwnProperty("base_url")&&(this.base_url=this.options.base_url,delete this.options.base_url),this.urls={forward:this.base_url+"forward",reverse:this.base_url+"reverse",autosuggest:this.base_url+"autosuggest",standardblend:this.base_url+"standardblend",autosuggest_ml:this.base_url+"autosuggest-ml",standardblend_ml:this.base_url+"standardblend-ml",grid:this.base_url+"grid",languages:this.base_url+"languages"}},a.Geocoder.prototype.forward=function(b,c){if("undefined"==typeof b||"object"!=typeof b)throw new Error("Missing or invalid params object");if(b){if(!b.hasOwnProperty("addr"))throw new Error("The params object is missing required addr property");if("string"!=typeof b.addr)throw new Error("params.addr must be a string");if(b.hasOwnProperty("lang")&&"string"!=typeof b.lang)throw new Error("params.lang must be a string");if(b.hasOwnProperty("format")){if("string"!=typeof b.format)throw new Error("params.format must be a string");if("json"!==b.format&&"geojson"!==b.format)throw new Error('params.format must have a value of "json" or "geojson"')}}if("undefined"==typeof c)throw new Error("Missing callback parameter");if("object"!=typeof c)throw new Error("Missing or invalid callback parameter");b=a.Utils.mergeOptions(this.options,b);var d=this.urls.forward+"?"+a.Utils.assembleQuery(b);a.Xhr.handleRequest(d,c)},a.Geocoder.prototype.reverse=function(b,c){if("undefined"==typeof b||"object"!=typeof b)throw new Error("Missing or invalid params object");if(b){if(!b.hasOwnProperty("coords"))throw new Error("The params object is missing required coords property");if(b.coords=this._formatCoords(b.coords),null===b.coords)throw new Error("Invalid format coordinates for params.coords");if(b.hasOwnProperty("lang")&&"string"!=typeof b.lang)throw new Error("params.lang must be a string");if(b.hasOwnProperty("format")){if("string"!=typeof b.format)throw new Error("params.format must be a string");if("json"!==b.format&&"geojson"!==b.format)throw new Error('params.format must have a value of "json" or "geojson"')}}if("undefined"==typeof c)throw new Error("Missing callback parameter");if("object"!=typeof c)throw new Error("Missing or invalid callback parameter");b=a.Utils.mergeOptions(this.options,b);var d=this.urls.reverse+"?"+a.Utils.assembleQuery(b);a.Xhr.handleRequest(d,c)},a.Geocoder.prototype.autosuggest=function(b,c){if("undefined"==typeof b||"object"!=typeof b)throw new Error("Missing or invalid params object");var d={};if(b){if(!b.hasOwnProperty("addr"))throw new Error("The params object is missing required addr property");if("string"!=typeof b.addr)throw new Error("params.addr must be a string");if(b.hasOwnProperty("focus")&&(b.focus=this._formatCoords(b.focus),null===b.focus))throw new Error("Invalid format coordinates for params.focus");if(!b.hasOwnProperty("lang"))throw new Error("The params object is missing required lang property");if("string"!=typeof b.lang)throw new Error("params.lang must be a string");if(b.hasOwnProperty("format")){if("string"!=typeof b.format)throw new Error("params.format must be a string");if("json"!==b.format)throw new Error('params.format must have a value of "json"')}if(b.hasOwnProperty("clip")){if(!b.clip.hasOwnProperty("type"))throw new Error("Invalid clipping policy type for params.clip");switch(b.clip.type){case"none":d={clip:"none"};break;case"radius":if(!b.clip.hasOwnProperty("distance"))throw new Error("Invalid clipping policy for type radius; missing distance property");if(!b.clip.hasOwnProperty("focus"))throw new Error("Invalid clipping policy for type radius; missing focus property");if(b.clip.focus=this._formatCoords(b.clip.focus),null===b.focus)throw new Error("Invalid format coordinates for params.clip.focus");d={clip:"radius("+b.clip.focus+","+b.clip.distance+")"};break;case"focus":if(!b.clip.hasOwnProperty("distance"))throw new Error("Invalid clipping policy for type focus; missing distance property");if(!b.hasOwnProperty("focus")||null===b.focus)throw new Error("Invalid clipping policy for type focus; missing or invalid focus property");d={clip:"focus("+b.clip.distance+")"};break;case"bbox":if(!b.clip.hasOwnProperty("bbox"))throw new Error("Invalid clipping policy for type bbox; missing bbox property");if(b.clip.bbox=this._formatBoundingBox(b.clip.bbox),null===b.clip.bbox)throw new Error("Invalid format coordinates for params.clip.bbox");d={clip:"bbox("+b.clip.bbox+")"};break;default:throw new Error("Invalid or unrecognised clipping policy type")}}}if("undefined"==typeof c)throw new Error("Missing callback parameter");if("object"!=typeof c)throw new Error("Missing or invalid callback parameter");b=a.Utils.mergeOptions(this.options,b,d);var e=this.urls.autosuggest+"?"+a.Utils.assembleQuery(b);a.Xhr.handleRequest(e,c)},a.Geocoder.prototype.autosuggest_ml=function(b,c){if("undefined"==typeof b||"object"!=typeof b)throw new Error("Missing or invalid params object");var d={};if(b){if(!b.hasOwnProperty("addr"))throw new Error("The params object is missing required addr property");if("string"!=typeof b.addr)throw new Error("params.addr must be a string");if(b.hasOwnProperty("focus")&&(b.focus=this._formatCoords(b.focus),null===b.focus))throw new Error("Invalid format coordinates for params.focus");if(!b.hasOwnProperty("lang"))throw new Error("The params object is missing required lang property");if("string"!=typeof b.lang)throw new Error("params.lang must be a string");if(b.hasOwnProperty("format")){if("string"!=typeof b.format)throw new Error("params.format must be a string");if("json"!==b.format)throw new Error('params.format must have a value of "json"')}if(b.hasOwnProperty("clip")){if(!b.clip.hasOwnProperty("type"))throw new Error("Invalid clipping policy type for params.clip");switch(b.clip.type){case"none":d={clip:"none"};break;case"radius":if(!b.clip.hasOwnProperty("distance"))throw new Error("Invalid clipping policy for type radius; missing distance property");if(!b.clip.hasOwnProperty("focus"))throw new Error("Invalid clipping policy for type radius; missing focus property");if(b.clip.focus=this._formatCoords(b.clip.focus),null===b.focus)throw new Error("Invalid format coordinates for params.clip.focus");d={clip:"radius("+b.clip.focus+","+b.clip.distance+")"};break;case"focus":if(!b.clip.hasOwnProperty("distance"))throw new Error("Invalid clipping policy for type focus; missing distance property");if(!b.hasOwnProperty("focus")||null===b.focus)throw new Error("Invalid clipping policy for type focus; missing or invalid focus property");d={clip:"focus("+b.clip.distance+")"};break;case"bbox":if(!b.clip.hasOwnProperty("bbox"))throw new Error("Invalid clipping policy for type bbox; missing bbox property");if(b.clip.bbox=this._formatBoundingBox(b.clip.bbox),null===b.clip.bbox)throw new Error("Invalid format coordinates for params.clip.bbox");d={clip:"bbox("+b.clip.bbox+")"};break;default:throw new Error("Invalid or unrecognised clipping policy type")}}}if("undefined"==typeof c)throw new Error("Missing callback parameter");if("object"!=typeof c)throw new Error("Missing or invalid callback parameter");b=a.Utils.mergeOptions(this.options,b,d);var e=this.urls.autosuggest_ml+"?"+a.Utils.assembleQuery(b);a.Xhr.handleRequest(e,c)},a.Geocoder.prototype.standardblend=function(b,c){if("undefined"==typeof b||"object"!=typeof b)throw new Error("Missing or invalid params object");if(b){if(!b.hasOwnProperty("addr"))throw new Error("The params object is missing required addr property");if("string"!=typeof b.addr)throw new Error("params.addr must be a string");if(b.hasOwnProperty("focus")&&(b.focus=this._formatCoords(b.focus),null===b.focus))throw new Error("Invalid format coordinates for params.focus");if(!b.hasOwnProperty("lang"))throw new Error("The params object is missing required lang property");if("string"!=typeof b.lang)throw new Error("params.lang must be a string");if(b.hasOwnProperty("format")){if("string"!=typeof b.format)throw new Error("params.format must be a string");if("json"!==b.format)throw new Error('params.format must have a value of "json"')}}if("undefined"==typeof c)throw new Error("Missing callback parameter");if("object"!=typeof c)throw new Error("Missing or invalid callback parameter");b=a.Utils.mergeOptions(this.options,b);var d=this.urls.standardblend+"?"+a.Utils.assembleQuery(b);a.Xhr.handleRequest(d,c)},a.Geocoder.prototype.standardblend_ml=function(b,c){if("undefined"==typeof b||"object"!=typeof b)throw new Error("Missing or invalid params object");if(b){if(!b.hasOwnProperty("addr"))throw new Error("The params object is missing required addr property");if("string"!=typeof b.addr)throw new Error("params.addr must be a string");if(b.hasOwnProperty("focus")&&(b.focus=this._formatCoords(b.focus),null===b.focus))throw new Error("Invalid format coordinates for params.focus");if(!b.hasOwnProperty("lang"))throw new Error("The params object is missing required lang property");if("string"!=typeof b.lang)throw new Error("params.lang must be a string");if(b.hasOwnProperty("format")){if("string"!=typeof b.format)throw new Error("params.format must be a string");if("json"!==b.format)throw new Error('params.format must have a value of "json"')}}if("undefined"==typeof c)throw new Error("Missing callback parameter");if("object"!=typeof c)throw new Error("Missing or invalid callback parameter");b=a.Utils.mergeOptions(this.options,b);var d=this.urls.standardblend_ml+"?"+a.Utils.assembleQuery(b);a.Xhr.handleRequest(d,c)},a.Geocoder.prototype.grid=function(b,c){if("undefined"==typeof b||"object"!=typeof b)throw new Error("Missing or invalid params object");if(b){if(!b.hasOwnProperty("bbox"))throw new Error("The params object is missing required bbox property");if(b.bbox=this._formatBoundingBox(b.bbox),null===b.bbox)throw new Error("Invalid format coordinates for params.bbox");if(b.hasOwnProperty("format")){if("string"!=typeof b.format)throw new Error("params.format must be a string");if("json"!==b.format&&"geojson"!==b.format)throw new Error('params.format must have a value of "json" or "geojson"')}}if("undefined"==typeof c)throw new Error("Missing callback parameter");if("object"!=typeof c)throw new Error("Missing or invalid callback parameter");b=a.Utils.mergeOptions(this.options,b);var d=this.urls.grid+"?"+a.Utils.assembleQuery(b);a.Xhr.handleRequest(d,c)},a.Geocoder.prototype.languages=function(b){if("undefined"==typeof b)throw new Error("Missing callback parameter");if("object"!=typeof b)throw new Error("Missing or invalid callback parameter");var c={key:this.options.key},d=this.urls.languages+"?"+a.Utils.assembleQuery(c);a.Xhr.handleRequest(d,b)},a.Geocoder.prototype._formatCoords=function(a){return"object"==typeof a&&a instanceof Array&&2===a.length?a.join(","):"string"==typeof a||a.match(/^[-.0-9]{1,},[-.0-9]{1,}$/)?null:a},a.Geocoder.prototype._formatBoundingBox=function(a){return"object"==typeof a&&a instanceof Array&&4===a.length?a.join(","):"string"==typeof a||a.match(/^[-.0-9]{1,},[-.0-9]{1,},[-.0-9]{1,},[-.0-9]{1,}$/)?null:a}}();