src/pyams_gis/resources/js/leaflet-gp-3.0.2.js
changeset 0 c73bb834ccbe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_gis/resources/js/leaflet-gp-3.0.2.js	Thu May 18 17:23:48 2017 +0200
@@ -0,0 +1,25289 @@
+/*!
+ * @brief Geoportal Extension for Leaflet
+ *
+ * This software is released under the licence CeCILL-B (Free BSD compatible)
+ * @see http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
+ * @see http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
+ * @see http://www.cecill.info/
+ *
+ * copyright CeCILL-B
+ * copyright IGN
+ * @author IGN
+ * @version 0.8.1
+ * @date 2016-12-02
+ *
+ */
+/*!
+ * @overview es6-promise - a tiny implementation of Promises/A+.
+ * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and cont  ributors (Conversion to ES6 API by Jake Archibald)
+ * @license   Licensed under MIT license
+ *            See https://raw.githubusercontent.com/jakearchibald/es6-promise/  master/LICENSE
+ * @version   3.0.2
+ */
+/*!
+ * Sortable -- minimalist JavaScript library for reorderable drag-and-drop lists
+ *
+ * Released under MIT LICENSE
+ * 
+ * Copyright 2013-2016 Lebedev Konstantin <ibnRubaXa@gmail.com>
+ * http://rubaxa.github.io/Sortable/
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*!
+ * Proj4js - Javascript reprojection library. 
+ * 
+ * Authors:
+ * 
+ * - Mike Adair madairATdmsolutions.ca
+ * - Richard Greenwood richATgreenwoodmap.com
+ * - Didier Richard didier.richardATign.fr
+ * - Stephen Irons stephen.ironsATclear.net.nz
+ * - Olivier Terral oterralATgmail.com
+ * - Calvin Metcalf cmetcalfATappgeo.com
+ * 
+ * Copyright (c) 2014, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral and Calvin Metcalf
+ * 
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),
+ *  to deal in the Software without restriction, including without limitation
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ *  Software is furnished to do so, subject to the following conditions:
+ * 
+ *  The above copyright notice and this permission notice shall be included
+ *  in all copies or substantial portions of the Software.
+ * 
+ *  _THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ *  DEALINGS IN THE SOFTWARE._
+ * 
+ */
+/*!
+ * Copyright 2012-2016 Jacob Toye and Leaflet
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*!
+ * Proj4Leaflet --  Smooth Proj4js integration with Leaflet
+ * 
+ * Copyright (c) 2012, Kartena AB
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+;(function(root, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['leaflet'], factory);
+  } else if (typeof exports === 'object') {
+    module.exports = factory(require('leaflet'));
+  } else {
+    root.Gp = factory(root.L);
+  }
+}(this, function(leaflet) {
+
+var gp, CommonUtilsAutoLoadConfig, leafletDraw, sortable, CommonControlsLayerSwitcherDOM, LeafletControlsLayerSwitcher, CommonUtilsConfig, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, CommonControlsLocationSelectorDOM, LeafletControlsUtilsPositionFormater, LeafletControlsUtilsIconDefault, LeafletControlsLocationSelector, CommonControlsIsoDOM, LeafletControlsIsocurve, CommonControlsMousePositionDOM, proj4, proj4leaflet07x, proj4leaflet10x, LeafletCRSProj4Leaflet, CommonUtilsRegister, LeafletCRSEPSG2154, LeafletCRSEPSG27572, LeafletCRSEPSG4326, LeafletCRSCRS, LeafletControlsMousePosition, CommonControlsReverseGeocodingDOM, LeafletControlsReverseGeocoding, CommonControlsRouteDOM, LeafletControlsRoute, CommonControlsSearchEngineDOM, CommonControlsSearchEngineUtils, LeafletControlsSearchEngine, CommonControlsElevationPathDOM, LeafletControlsElevationPath, LeafletControlsLogo, LeafletControlsControls, CommonUtilsLayerUtils, LeafletLayersLayerConfig, LeafletLayersLayerEvent, LeafletLayersWMS, LeafletLayersWMTS, LeafletLayersLayers, LeafletGpPluginLeaflet;
+(function (root, factory) {
+    if (true) {
+        gp = function () {
+            return typeof factory === 'function' ? factory() : factory;
+        }();
+    } else if (typeof exports === 'object') {
+        module.exports = factory();
+    } else {
+        root.Gp = factory();
+    }
+}(this, function () {
+    var log4js, loggerCfg, UtilsLoggerByDefault, UtilsHelper, promise, ProtocolsXHR, UtilsMessagesResources, ExceptionsErrorService, ProtocolsJSONP, ProtocolsProtocol, ServicesDefaultUrlService, ServicesCommonService, ServicesAltiRequestModelAltiRequest, ServicesAltiRequestModelAltiElevationRequest, ServicesAltiRequestModelAltiProfilRequest, ServicesAltiRequestAltiRequestREST, FormatsWPS, ServicesAltiRequestAltiRequestWPS, ServicesAltiRequestAltiRequestFactory, FormatsXML, ServicesAltiResponseModelAltiResponse, ServicesAltiResponseModelElevation, ServicesAltiFormatsAltiResponseReader, ServicesAltiResponseAltiResponseFactory, ServicesAltiAlti, ServicesAutoConfResponseModelAutoConfResponse, ServicesAutoConfResponseModelConstraint, ServicesAutoConfResponseModelFormat, ServicesAutoConfResponseModelLayer, ServicesAutoConfResponseModelLegend, ServicesAutoConfResponseModelMetadata, ServicesAutoConfResponseModelOriginator, ServicesAutoConfResponseModelService, ServicesAutoConfResponseModelStyle, ServicesAutoConfResponseModelTerritory, ServicesAutoConfResponseModelThematic, ServicesAutoConfResponseModelTileMatrixSet, ServicesAutoConfResponseModelTileMatrix, ServicesAutoConfResponseModelTileMatrixLimit, ServicesAutoConfFormatsAutoConfResponseReader, ServicesAutoConfResponseAutoConfResponseFactory, ServicesAutoConfAutoConf, FormatsXLSRequestHeader, FormatsXLSRequest, FormatsXLSAbstractService, FormatsXLS, FormatsXLSLocationUtilityServiceModelAddress, FormatsXLSLocationUtilityServiceGeocodeFilterExtension, FormatsXLSLocationUtilityServiceGeocodeRequest, FormatsXLSLocationUtilityServiceModelPosition, FormatsXLSLocationUtilityServiceModelPreference, FormatsXLSLocationUtilityServiceReverseGeocodeRequest, FormatsXLSLocationUtilityService, ServicesGeocodeRequestGeocodeLocation, ServicesGeocodeRequestModelStreetAddress, ServicesGeocodeRequestModelPositionOfInterest, ServicesGeocodeRequestModelCadastralParcel, ServicesGeocodeRequestModelAdministratif, ServicesGeocodeRequestDirectGeocodeRequestFactory, ServicesGeocodeResponseModelGeocodeResponse, ServicesGeocodeResponseModelGeocodedLocation, ServicesGeocodeResponseModelDirectGeocodedLocation, ServicesGeocodeFormatsDirectGeocodeResponseReader, ServicesGeocodeResponseDirectGeocodeResponseFactory, ServicesGeocodeGeocode, ServicesGeocodeRequestReverseGeocodeRequestFactory, ServicesGeocodeResponseModelReverseGeocodedLocation, ServicesGeocodeFormatsReverseGeocodeResponseReader, ServicesGeocodeResponseReverseGeocodeResponseFactory, ServicesGeocodeReverseGeocode, ServicesAutoCompleteResponseModelAutoCompleteResponse, ServicesAutoCompleteResponseModelSuggestedLocation, ServicesAutoCompleteResponseAutoCompleteResponseFactory, ServicesAutoCompleteAutoComplete, FormatsXLSRouteServiceModelRoutePlan, FormatsXLSRouteServiceDetermineRouteRequest, FormatsXLSRouteServiceRouteRequestExtension, FormatsXLSRouteService, ServicesRouteRequestRouteRequestOLS, ServicesRouteRequestModelRouteParamREST, ServicesRouteRequestRouteRequestREST, ServicesRouteRequestRouteRequestFactory, FormatsWKT, ServicesRouteResponseModelRouteResponse, ServicesRouteResponseModelRouteInstruction, ServicesRouteFormatsRouteResponseRESTReader, ServicesRouteFormatsRouteResponseOLSReader, ServicesRouteResponseRouteResponseFactory, ServicesRouteRoute, ServicesProcessIsoCurveRequestModelProcessIsoCurveParam, ServicesProcessIsoCurveRequestProcessIsoCurveRequest, ServicesProcessIsoCurveResponseModelProcessIsoCurveResponse, ServicesProcessIsoCurveFormatsProcessIsoCurveResponseReader, ServicesProcessIsoCurveResponseProcessIsoCurveResponseFactory, ServicesProcessIsoCurveProcessIsoCurve, ServicesServices, Gp;
+    log4js = undefined;
+    loggerCfg = {
+        loggers: [{
+                root: true,
+                level: 'all',
+                appenders: [{
+                        type: 'Console',
+                        layout: {
+                            type: 'PatternLayout',
+                            pattern: '%d{yyyy-MM-dd HH:mm:ss} [%p] %c - %m%n'
+                        }
+                    }]
+            }]
+    };
+    UtilsLoggerByDefault = function (Log4js, Config) {
+        var LoggerByDefault = {
+            getLogger: function (name) {
+                Log4js.load(Config, function (error) {
+                    if (error) {
+                        throw error;
+                    }
+                });
+                var logname = name || 'default';
+                return Log4js.getLogger(logname);
+            }
+        };
+        return LoggerByDefault;
+    }(log4js, loggerCfg);
+    UtilsHelper = function () {
+        var Helper = {
+            normalyzeParameters: function (params) {
+                var myParams = null;
+                if (params) {
+                    var tabParams = [];
+                    for (var key in params) {
+                        if (params.hasOwnProperty(key)) {
+                            var value = params[key];
+                            if (!value) {
+                                value = '';
+                            }
+                            tabParams.push(key + '=' + value);
+                        }
+                    }
+                    myParams = tabParams.join('&');
+                }
+                return myParams;
+            },
+            normalyzeUrl: function (url, params, encode) {
+                var myUrl = url;
+                if (url) {
+                    var k = url.indexOf('?');
+                    if (k === -1) {
+                        myUrl += '?';
+                    }
+                    if (k !== -1 && k !== url.length - 1) {
+                        myUrl += '&';
+                    }
+                }
+                if (params) {
+                    if (typeof params === 'string') {
+                        myUrl += params;
+                    } else {
+                        myUrl += this.normalyzeParameters(params);
+                    }
+                }
+                if (encode) {
+                    myUrl = encodeURIComponent(myUrl);
+                }
+                return myUrl;
+            },
+            indent: function (n, msg) {
+                var num = n || 0;
+                return new Array(num + 1).join('\t') + msg;
+            }
+        };
+        return Helper;
+    }();
+    (function () {
+        'use strict';
+        function lib$es6$promise$utils$$objectOrFunction(x) {
+            return typeof x === 'function' || typeof x === 'object' && x !== null;
+        }
+        function lib$es6$promise$utils$$isFunction(x) {
+            return typeof x === 'function';
+        }
+        function lib$es6$promise$utils$$isMaybeThenable(x) {
+            return typeof x === 'object' && x !== null;
+        }
+        var lib$es6$promise$utils$$_isArray;
+        if (!Array.isArray) {
+            lib$es6$promise$utils$$_isArray = function (x) {
+                return Object.prototype.toString.call(x) === '[object Array]';
+            };
+        } else {
+            lib$es6$promise$utils$$_isArray = Array.isArray;
+        }
+        var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;
+        var lib$es6$promise$asap$$len = 0;
+        var lib$es6$promise$asap$$toString = {}.toString;
+        var lib$es6$promise$asap$$vertxNext;
+        var lib$es6$promise$asap$$customSchedulerFn;
+        var lib$es6$promise$asap$$asap = function asap(callback, arg) {
+            lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;
+            lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;
+            lib$es6$promise$asap$$len += 2;
+            if (lib$es6$promise$asap$$len === 2) {
+                if (lib$es6$promise$asap$$customSchedulerFn) {
+                    lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);
+                } else {
+                    lib$es6$promise$asap$$scheduleFlush();
+                }
+            }
+        };
+        function lib$es6$promise$asap$$setScheduler(scheduleFn) {
+            lib$es6$promise$asap$$customSchedulerFn = scheduleFn;
+        }
+        function lib$es6$promise$asap$$setAsap(asapFn) {
+            lib$es6$promise$asap$$asap = asapFn;
+        }
+        var lib$es6$promise$asap$$browserWindow = typeof window !== 'undefined' ? window : undefined;
+        var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};
+        var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;
+        var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
+        var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
+        function lib$es6$promise$asap$$useNextTick() {
+            return function () {
+                process.nextTick(lib$es6$promise$asap$$flush);
+            };
+        }
+        function lib$es6$promise$asap$$useVertxTimer() {
+            return function () {
+                lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);
+            };
+        }
+        function lib$es6$promise$asap$$useMutationObserver() {
+            var iterations = 0;
+            var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);
+            var node = document.createTextNode('');
+            observer.observe(node, { characterData: true });
+            return function () {
+                node.data = iterations = ++iterations % 2;
+            };
+        }
+        function lib$es6$promise$asap$$useMessageChannel() {
+            var channel = new MessageChannel();
+            channel.port1.onmessage = lib$es6$promise$asap$$flush;
+            return function () {
+                channel.port2.postMessage(0);
+            };
+        }
+        function lib$es6$promise$asap$$useSetTimeout() {
+            return function () {
+                setTimeout(lib$es6$promise$asap$$flush, 1);
+            };
+        }
+        var lib$es6$promise$asap$$queue = new Array(1000);
+        function lib$es6$promise$asap$$flush() {
+            for (var i = 0; i < lib$es6$promise$asap$$len; i += 2) {
+                var callback = lib$es6$promise$asap$$queue[i];
+                var arg = lib$es6$promise$asap$$queue[i + 1];
+                callback(arg);
+                lib$es6$promise$asap$$queue[i] = undefined;
+                lib$es6$promise$asap$$queue[i + 1] = undefined;
+            }
+            lib$es6$promise$asap$$len = 0;
+        }
+        function lib$es6$promise$asap$$attemptVertx() {
+            try {
+                var r = require;
+                var vertx = r('vertx');
+                lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;
+                return lib$es6$promise$asap$$useVertxTimer();
+            } catch (e) {
+                return lib$es6$promise$asap$$useSetTimeout();
+            }
+        }
+        var lib$es6$promise$asap$$scheduleFlush;
+        if (lib$es6$promise$asap$$isNode) {
+            lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();
+        } else if (lib$es6$promise$asap$$BrowserMutationObserver) {
+            lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();
+        } else if (lib$es6$promise$asap$$isWorker) {
+            lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();
+        } else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {
+            lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertx();
+        } else {
+            lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();
+        }
+        function lib$es6$promise$$internal$$noop() {
+        }
+        var lib$es6$promise$$internal$$PENDING = void 0;
+        var lib$es6$promise$$internal$$FULFILLED = 1;
+        var lib$es6$promise$$internal$$REJECTED = 2;
+        var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();
+        function lib$es6$promise$$internal$$selfFulfillment() {
+            return new TypeError('You cannot resolve a promise with itself');
+        }
+        function lib$es6$promise$$internal$$cannotReturnOwn() {
+            return new TypeError('A promises callback cannot return that same promise.');
+        }
+        function lib$es6$promise$$internal$$getThen(promise) {
+            try {
+                return promise.then;
+            } catch (error) {
+                lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;
+                return lib$es6$promise$$internal$$GET_THEN_ERROR;
+            }
+        }
+        function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
+            try {
+                then.call(value, fulfillmentHandler, rejectionHandler);
+            } catch (e) {
+                return e;
+            }
+        }
+        function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {
+            lib$es6$promise$asap$$asap(function (promise) {
+                var sealed = false;
+                var error = lib$es6$promise$$internal$$tryThen(then, thenable, function (value) {
+                    if (sealed) {
+                        return;
+                    }
+                    sealed = true;
+                    if (thenable !== value) {
+                        lib$es6$promise$$internal$$resolve(promise, value);
+                    } else {
+                        lib$es6$promise$$internal$$fulfill(promise, value);
+                    }
+                }, function (reason) {
+                    if (sealed) {
+                        return;
+                    }
+                    sealed = true;
+                    lib$es6$promise$$internal$$reject(promise, reason);
+                }, 'Settle: ' + (promise._label || ' unknown promise'));
+                if (!sealed && error) {
+                    sealed = true;
+                    lib$es6$promise$$internal$$reject(promise, error);
+                }
+            }, promise);
+        }
+        function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {
+            if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {
+                lib$es6$promise$$internal$$fulfill(promise, thenable._result);
+            } else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {
+                lib$es6$promise$$internal$$reject(promise, thenable._result);
+            } else {
+                lib$es6$promise$$internal$$subscribe(thenable, undefined, function (value) {
+                    lib$es6$promise$$internal$$resolve(promise, value);
+                }, function (reason) {
+                    lib$es6$promise$$internal$$reject(promise, reason);
+                });
+            }
+        }
+        function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {
+            if (maybeThenable.constructor === promise.constructor) {
+                lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);
+            } else {
+                var then = lib$es6$promise$$internal$$getThen(maybeThenable);
+                if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {
+                    lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);
+                } else if (then === undefined) {
+                    lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
+                } else if (lib$es6$promise$utils$$isFunction(then)) {
+                    lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);
+                } else {
+                    lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
+                }
+            }
+        }
+        function lib$es6$promise$$internal$$resolve(promise, value) {
+            if (promise === value) {
+                lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFulfillment());
+            } else if (lib$es6$promise$utils$$objectOrFunction(value)) {
+                lib$es6$promise$$internal$$handleMaybeThenable(promise, value);
+            } else {
+                lib$es6$promise$$internal$$fulfill(promise, value);
+            }
+        }
+        function lib$es6$promise$$internal$$publishRejection(promise) {
+            if (promise._onerror) {
+                promise._onerror(promise._result);
+            }
+            lib$es6$promise$$internal$$publish(promise);
+        }
+        function lib$es6$promise$$internal$$fulfill(promise, value) {
+            if (promise._state !== lib$es6$promise$$internal$$PENDING) {
+                return;
+            }
+            promise._result = value;
+            promise._state = lib$es6$promise$$internal$$FULFILLED;
+            if (promise._subscribers.length !== 0) {
+                lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);
+            }
+        }
+        function lib$es6$promise$$internal$$reject(promise, reason) {
+            if (promise._state !== lib$es6$promise$$internal$$PENDING) {
+                return;
+            }
+            promise._state = lib$es6$promise$$internal$$REJECTED;
+            promise._result = reason;
+            lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);
+        }
+        function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
+            var subscribers = parent._subscribers;
+            var length = subscribers.length;
+            parent._onerror = null;
+            subscribers[length] = child;
+            subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;
+            subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection;
+            if (length === 0 && parent._state) {
+                lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);
+            }
+        }
+        function lib$es6$promise$$internal$$publish(promise) {
+            var subscribers = promise._subscribers;
+            var settled = promise._state;
+            if (subscribers.length === 0) {
+                return;
+            }
+            var child, callback, detail = promise._result;
+            for (var i = 0; i < subscribers.length; i += 3) {
+                child = subscribers[i];
+                callback = subscribers[i + settled];
+                if (child) {
+                    lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);
+                } else {
+                    callback(detail);
+                }
+            }
+            promise._subscribers.length = 0;
+        }
+        function lib$es6$promise$$internal$$ErrorObject() {
+            this.error = null;
+        }
+        var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();
+        function lib$es6$promise$$internal$$tryCatch(callback, detail) {
+            try {
+                return callback(detail);
+            } catch (e) {
+                lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;
+                return lib$es6$promise$$internal$$TRY_CATCH_ERROR;
+            }
+        }
+        function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {
+            var hasCallback = lib$es6$promise$utils$$isFunction(callback), value, error, succeeded, failed;
+            if (hasCallback) {
+                value = lib$es6$promise$$internal$$tryCatch(callback, detail);
+                if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {
+                    failed = true;
+                    error = value.error;
+                    value = null;
+                } else {
+                    succeeded = true;
+                }
+                if (promise === value) {
+                    lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());
+                    return;
+                }
+            } else {
+                value = detail;
+                succeeded = true;
+            }
+            if (promise._state !== lib$es6$promise$$internal$$PENDING) {
+            } else if (hasCallback && succeeded) {
+                lib$es6$promise$$internal$$resolve(promise, value);
+            } else if (failed) {
+                lib$es6$promise$$internal$$reject(promise, error);
+            } else if (settled === lib$es6$promise$$internal$$FULFILLED) {
+                lib$es6$promise$$internal$$fulfill(promise, value);
+            } else if (settled === lib$es6$promise$$internal$$REJECTED) {
+                lib$es6$promise$$internal$$reject(promise, value);
+            }
+        }
+        function lib$es6$promise$$internal$$initializePromise(promise, resolver) {
+            try {
+                resolver(function resolvePromise(value) {
+                    lib$es6$promise$$internal$$resolve(promise, value);
+                }, function rejectPromise(reason) {
+                    lib$es6$promise$$internal$$reject(promise, reason);
+                });
+            } catch (e) {
+                lib$es6$promise$$internal$$reject(promise, e);
+            }
+        }
+        function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {
+            var enumerator = this;
+            enumerator._instanceConstructor = Constructor;
+            enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);
+            if (enumerator._validateInput(input)) {
+                enumerator._input = input;
+                enumerator.length = input.length;
+                enumerator._remaining = input.length;
+                enumerator._init();
+                if (enumerator.length === 0) {
+                    lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
+                } else {
+                    enumerator.length = enumerator.length || 0;
+                    enumerator._enumerate();
+                    if (enumerator._remaining === 0) {
+                        lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
+                    }
+                }
+            } else {
+                lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());
+            }
+        }
+        lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function (input) {
+            return lib$es6$promise$utils$$isArray(input);
+        };
+        lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function () {
+            return new Error('Array Methods must be provided an Array');
+        };
+        lib$es6$promise$enumerator$$Enumerator.prototype._init = function () {
+            this._result = new Array(this.length);
+        };
+        var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;
+        lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function () {
+            var enumerator = this;
+            var length = enumerator.length;
+            var promise = enumerator.promise;
+            var input = enumerator._input;
+            for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
+                enumerator._eachEntry(input[i], i);
+            }
+        };
+        lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function (entry, i) {
+            var enumerator = this;
+            var c = enumerator._instanceConstructor;
+            if (lib$es6$promise$utils$$isMaybeThenable(entry)) {
+                if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {
+                    entry._onerror = null;
+                    enumerator._settledAt(entry._state, i, entry._result);
+                } else {
+                    enumerator._willSettleAt(c.resolve(entry), i);
+                }
+            } else {
+                enumerator._remaining--;
+                enumerator._result[i] = entry;
+            }
+        };
+        lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function (state, i, value) {
+            var enumerator = this;
+            var promise = enumerator.promise;
+            if (promise._state === lib$es6$promise$$internal$$PENDING) {
+                enumerator._remaining--;
+                if (state === lib$es6$promise$$internal$$REJECTED) {
+                    lib$es6$promise$$internal$$reject(promise, value);
+                } else {
+                    enumerator._result[i] = value;
+                }
+            }
+            if (enumerator._remaining === 0) {
+                lib$es6$promise$$internal$$fulfill(promise, enumerator._result);
+            }
+        };
+        lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function (promise, i) {
+            var enumerator = this;
+            lib$es6$promise$$internal$$subscribe(promise, undefined, function (value) {
+                enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);
+            }, function (reason) {
+                enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);
+            });
+        };
+        function lib$es6$promise$promise$all$$all(entries) {
+            return new lib$es6$promise$enumerator$$default(this, entries).promise;
+        }
+        var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;
+        function lib$es6$promise$promise$race$$race(entries) {
+            var Constructor = this;
+            var promise = new Constructor(lib$es6$promise$$internal$$noop);
+            if (!lib$es6$promise$utils$$isArray(entries)) {
+                lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));
+                return promise;
+            }
+            var length = entries.length;
+            function onFulfillment(value) {
+                lib$es6$promise$$internal$$resolve(promise, value);
+            }
+            function onRejection(reason) {
+                lib$es6$promise$$internal$$reject(promise, reason);
+            }
+            for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
+                lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
+            }
+            return promise;
+        }
+        var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;
+        function lib$es6$promise$promise$resolve$$resolve(object) {
+            var Constructor = this;
+            if (object && typeof object === 'object' && object.constructor === Constructor) {
+                return object;
+            }
+            var promise = new Constructor(lib$es6$promise$$internal$$noop);
+            lib$es6$promise$$internal$$resolve(promise, object);
+            return promise;
+        }
+        var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;
+        function lib$es6$promise$promise$reject$$reject(reason) {
+            var Constructor = this;
+            var promise = new Constructor(lib$es6$promise$$internal$$noop);
+            lib$es6$promise$$internal$$reject(promise, reason);
+            return promise;
+        }
+        var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;
+        var lib$es6$promise$promise$$counter = 0;
+        function lib$es6$promise$promise$$needsResolver() {
+            throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
+        }
+        function lib$es6$promise$promise$$needsNew() {
+            throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.');
+        }
+        var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;
+        function lib$es6$promise$promise$$Promise(resolver) {
+            this._id = lib$es6$promise$promise$$counter++;
+            this._state = undefined;
+            this._result = undefined;
+            this._subscribers = [];
+            if (lib$es6$promise$$internal$$noop !== resolver) {
+                if (!lib$es6$promise$utils$$isFunction(resolver)) {
+                    lib$es6$promise$promise$$needsResolver();
+                }
+                if (!(this instanceof lib$es6$promise$promise$$Promise)) {
+                    lib$es6$promise$promise$$needsNew();
+                }
+                lib$es6$promise$$internal$$initializePromise(this, resolver);
+            }
+        }
+        lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;
+        lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;
+        lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;
+        lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;
+        lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;
+        lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;
+        lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;
+        lib$es6$promise$promise$$Promise.prototype = {
+            constructor: lib$es6$promise$promise$$Promise,
+            then: function (onFulfillment, onRejection) {
+                var parent = this;
+                var state = parent._state;
+                if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {
+                    return this;
+                }
+                var child = new this.constructor(lib$es6$promise$$internal$$noop);
+                var result = parent._result;
+                if (state) {
+                    var callback = arguments[state - 1];
+                    lib$es6$promise$asap$$asap(function () {
+                        lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);
+                    });
+                } else {
+                    lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);
+                }
+                return child;
+            },
+            'catch': function (onRejection) {
+                return this.then(null, onRejection);
+            }
+        };
+        function lib$es6$promise$polyfill$$polyfill() {
+            var local;
+            if (typeof global !== 'undefined') {
+                local = global;
+            } else if (typeof self !== 'undefined') {
+                local = self;
+            } else {
+                try {
+                    local = Function('return this')();
+                } catch (e) {
+                    throw new Error('polyfill failed because global object is unavailable in this environment');
+                }
+            }
+            var P = local.Promise;
+            if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
+                return;
+            }
+            local.Promise = lib$es6$promise$promise$$default;
+        }
+        var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;
+        var lib$es6$promise$umd$$ES6Promise = {
+            'Promise': lib$es6$promise$promise$$default,
+            'polyfill': lib$es6$promise$polyfill$$default
+        };
+        if (true) {
+            promise = function () {
+                return lib$es6$promise$umd$$ES6Promise;
+            }();
+        } else if (typeof module !== 'undefined' && module['exports']) {
+            module['exports'] = lib$es6$promise$umd$$ES6Promise;
+        } else if (typeof this !== 'undefined') {
+            this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;
+        }
+        lib$es6$promise$polyfill$$default();
+    }.call(this));
+    ProtocolsXHR = function (Logger, Helper, ES6Promise) {
+        var XHR = {
+            call: function (settings) {
+                ES6Promise.polyfill();
+                if (!settings.url) {
+                    throw new Error('missing parameter : url is not defined !');
+                }
+                if (!settings.method) {
+                    throw new Error('missing parameter : method is not defined !');
+                }
+                if (!settings.format) {
+                    settings.format = 'text';
+                }
+                var options = {};
+                options.url = settings.url;
+                options.data = settings.data ? settings.data : null;
+                options.method = settings.method;
+                options.timeOut = settings.timeOut || 0;
+                options.scope = settings.scope || this;
+                switch (settings.method) {
+                case 'DELETE':
+                case 'GET':
+                    break;
+                case 'PUT':
+                case 'POST':
+                    options.content = settings.content ? settings.content : 'application/x-www-form-urlencoded';
+                    options.headers = settings.headers ? settings.headers : { referer: 'http://localhost' };
+                    break;
+                case 'HEAD':
+                case 'OPTIONS':
+                    throw new Error('HTTP method not yet supported !');
+                default:
+                    throw new Error('HTTP method unknown !');
+                }
+                switch (settings.format) {
+                case 'text':
+                    this.__call(options).then(function (response) {
+                        settings.onResponse.call(this, response);
+                    }).catch(function (error) {
+                        settings.onFailure.call(this, error);
+                    });
+                    break;
+                case 'json':
+                    this.__callJSON(options).then(function (response) {
+                        settings.onResponse.call(this, response);
+                    }).catch(function (error) {
+                        settings.onFailure.call(this, error);
+                    });
+                    break;
+                case 'xml':
+                    this.__callXML(options).then(function (response) {
+                        settings.onResponse.call(this, response);
+                    }).catch(function (error) {
+                        settings.onFailure.call(this, error);
+                    });
+                    break;
+                default:
+                    throw new Error('This output Format is not yet supported !');
+                }
+            },
+            __call: function (options) {
+                var promise = new Promise(function (resolve, reject) {
+                    var corps = options.method === 'POST' || options.method === 'PUT' ? true : false;
+                    if (options.data && !corps) {
+                        options.url = Helper.normalyzeUrl(options.url, options.data);
+                    }
+                    var hXHR = null;
+                    if (window.XMLHttpRequest) {
+                        hXHR = new XMLHttpRequest();
+                        hXHR.open(options.method, options.url, true);
+                        hXHR.overrideMimeType = options.content;
+                        var onTimeOutTrigger = null;
+                        if (options.timeOut > 0) {
+                            onTimeOutTrigger = window.setTimeout(function () {
+                                var message = 'TimeOut Occured on Http Request with XMLHttpRequest !';
+                                reject({
+                                    message: message,
+                                    status: -1
+                                });
+                            }, options.timeOut);
+                        }
+                        if (corps) {
+                            hXHR.setRequestHeader('Content-type', options.content);
+                        }
+                        hXHR.onerror = function (e) {
+                            console.log(e);
+                            reject(new Error('Errors Occured on Http Request with XMLHttpRequest !'));
+                        };
+                        hXHR.ontimeout = function () {
+                            reject(new Error('TimeOut Occured on Http Request with XMLHttpRequest !'));
+                        };
+                        hXHR.onreadystatechange = function () {
+                            if (hXHR.readyState == 4) {
+                                if (hXHR.status == 200) {
+                                    window.clearTimeout(onTimeOutTrigger);
+                                    resolve(hXHR.response);
+                                } else {
+                                    var message = 'Errors Occured on Http Request (status : \'' + hXHR.status + '\' | response : \'' + hXHR.response + '\')';
+                                    var status = hXHR.status;
+                                    reject({
+                                        message: message,
+                                        status: status
+                                    });
+                                }
+                            }
+                        };
+                        var data4xhr = options.data && corps ? options.data : null;
+                        hXHR.send(data4xhr);
+                    } else if (window.XDomainRequest) {
+                        hXHR = new XDomainRequest();
+                        hXHR.open(options.method, options.url);
+                        hXHR.overrideMimeType = options.content;
+                        if (options.timeOut > 0) {
+                            hXHR.timeout = options.timeout;
+                        }
+                        if (corps) {
+                            hXHR.setRequestHeader('Content-type', options.content);
+                        }
+                        hXHR.onerror = function () {
+                            reject(new Error('Errors Occured on Http Request with XMLHttpRequest !'));
+                        };
+                        hXHR.ontimeout = function () {
+                            reject(new Error('TimeOut Occured on Http Request with XMLHttpRequest !'));
+                        };
+                        hXHR.onload = function () {
+                            if (hXHR.status == 200) {
+                                resolve(hXHR.responseText);
+                            } else {
+                                var message = 'Errors Occured on Http Request (status : \'' + hXHR.status + '\' | response : \'' + hXHR.responseText + '\')';
+                                var status = hXHR.status;
+                                reject({
+                                    message: message,
+                                    status: status
+                                });
+                            }
+                        };
+                        var data4xdr = options.data && corps ? options.data : null;
+                        hXHR.send(data4xdr);
+                    } else {
+                        throw new Error('CORS not supported');
+                    }
+                });
+                return promise;
+            },
+            __callJSON: function (options) {
+                return this.__call(options).then(JSON.parse).catch(function (error) {
+                    console.log('_callJSON failed on : ', options.url, error);
+                    throw error;
+                });
+            },
+            __callXML: function (options) {
+                return this.__call(options).then(function (response) {
+                    var xmlDoc;
+                    if (window.DOMParser) {
+                        var parser = new DOMParser();
+                        xmlDoc = parser.parseFromString(response, 'text/xml');
+                    } else {
+                        xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM');
+                        xmlDoc.async = false;
+                        xmlDoc.loadXML(response);
+                    }
+                    return xmlDoc;
+                }).catch(function (error) {
+                    console.log('__callXML failed on : ', options.url, error);
+                    throw error;
+                });
+            }
+        };
+        return XHR;
+    }(UtilsLoggerByDefault, UtilsHelper, promise);
+    UtilsMessagesResources = function () {
+        var MessagesResources = {
+            PARAM_MISSING: 'Parameter(s) \'%var%\' missing',
+            PARAM_EMPTY: 'Parameter(s) \'%var%\' empty',
+            PARAM_TYPE: 'Wrong type(s) for parameter(s) \'%var%\'',
+            PARAM_FORMAT: 'Parameter(s) \'%var%\' not correctly formatted',
+            PARAM_NOT_SUPPORT: 'Value(s) for parameter(s) \'%var%\' not supported',
+            PARAM_UNKNOWN: 'Value(s) for parameter(s) \'%var%\' unknown',
+            SERVICE_REQUEST_BUILD: 'An error occurred during the request building of the service',
+            SERVICE_REQUEST_EMPTY: 'The request sent to the service is empty',
+            SERVICE_RESPONSE_EXCEPTION: 'The service returned an exception : \'%var%\'',
+            SERVICE_RESPONSE_EXCEPTION_2: 'The service returned an exception',
+            SERVICE_RESPONSE_ANALYSE: 'An error occurred while parsing the response \'%var%\' of the service',
+            SERVICE_RESPONSE_ANALYSE_2: 'An unknown error occurred while parsing the response',
+            SERVICE_RESPONSE_EMPTY: 'The response of the service is empty',
+            SERVICE_RESPONSE_EMPTY_2: 'The response from the service could not be analyzed or is empty',
+            SERVICE_RESPONSE_FORMAT: 'The format of the service response is not supported (handled format(s) : \'%var%\')',
+            SERVICE_RESPONSE_FORMAT_2: 'The format of the service response is not supported',
+            SERVICE_RESPONSE_FORMAT_3: 'No suggestion matching the search',
+            CLASS_CONSTRUCTOR: '\'%var%\' constructor cannot be called as a function.',
+            getMessage: function (clef, parametres) {
+                if (!arguments) {
+                    return 'Message indefined !';
+                }
+                var params = Array.prototype.slice.call(arguments);
+                var key = params.shift();
+                var args = params;
+                var message = this[key];
+                try {
+                    if (Array.isArray(args) && args.length > 0) {
+                        message = message.replace('%var%', args.join(' - '));
+                    } else {
+                        message = message.replace('%var%', '%var% (not specified)');
+                    }
+                } catch (e) {
+                }
+                return message;
+            }
+        };
+        return MessagesResources;
+    }();
+    ExceptionsErrorService = function () {
+        function ErrorService(error) {
+            if (!(this instanceof ErrorService)) {
+                throw new TypeError('ErrorService constructor cannot be called as a function.');
+            }
+            var e = error;
+            if (typeof error === 'string' || error instanceof String) {
+                this.message = error;
+                this.status = -1;
+                this.type = ErrorService.TYPE_UNKERR;
+            } else {
+                this.message = e.message || 'undefined!?';
+                this.type = e.type;
+                this.status = e.status || -1;
+            }
+            this.name = 'ErrorService';
+            this.stack = new Error().stack;
+        }
+        ErrorService.TYPE_SRVERR = 'SERVICE_ERROR';
+        ErrorService.TYPE_USEERR = 'USAGE_ERROR';
+        ErrorService.TYPE_UNKERR = 'UNKNOWN_ERROR';
+        ErrorService.prototype = Object.create(Error.prototype, {
+            constructor: {
+                value: ErrorService,
+                writable: true,
+                configurable: true
+            }
+        });
+        return ErrorService;
+    }();
+    ProtocolsJSONP = function (Logger) {
+        var JSONP = {
+            uuid: function () {
+                var id = Math.floor(Date.now());
+                return function () {
+                    return id++;
+                };
+            }(),
+            call: function (options) {
+                if (!options) {
+                    throw new Error('missing parameter : options !');
+                }
+                if (!options.url) {
+                    throw new Error('missing parameter : options.url !');
+                }
+                if (!options.timeOut) {
+                    options.timeOut = 0;
+                }
+                if (!options.onResponse) {
+                    throw new Error('missing parameter : options.onResponse !');
+                }
+                var callbackId = typeof options.callbackSuffix === 'string' ? options.callbackSuffix : this.uuid();
+                var urlHasCallbackKey = false;
+                var urlHasCallbackName = false;
+                var idx = options.url.indexOf('callback=');
+                if (idx != -1) {
+                    urlHasCallbackKey = true;
+                    var j = options.url.indexOf('&', idx);
+                    if (j === -1) {
+                        j = options.url.length;
+                    }
+                    var callbackName = options.url.substring(idx + 9, j);
+                    if (callbackName) {
+                        urlHasCallbackName = true;
+                        options.callbackName = callbackName;
+                    }
+                }
+                if (!urlHasCallbackKey) {
+                    var k = options.url.indexOf('?');
+                    if (k === -1) {
+                        options.url = options.url + '?' + 'callback=';
+                    } else if (k === options.url.length) {
+                        options.url = options.url + 'callback=';
+                    } else {
+                        options.url = options.url + '&' + 'callback=';
+                    }
+                }
+                var HasCallbackName = options.callbackName ? true : urlHasCallbackName;
+                if (!urlHasCallbackName) {
+                    if (!options.callbackName) {
+                        options.callbackName = 'callback';
+                        if (callbackId || callbackId === '') {
+                            options.callbackName += callbackId;
+                        }
+                    }
+                    options.url = options.url.replace('callback=', 'callback=' + options.callbackName);
+                }
+                if (!options.onTimeOut) {
+                    options.onTimeOut = function () {
+                        console.log('TimeOut while invoking url : ' + options.url);
+                    };
+                }
+                if (!HasCallbackName) {
+                    var self = this;
+                    var onTimeOutTrigger = null;
+                    if (options.timeOut > 0) {
+                        onTimeOutTrigger = window.setTimeout(function () {
+                            window[options.callbackName] = function () {
+                            };
+                            options.onTimeOut();
+                            self._deleteScript(callbackId);
+                        }, options.timeOut);
+                    }
+                    window[options.callbackName] = function (data) {
+                        window.clearTimeout(onTimeOutTrigger);
+                        options.onResponse(data);
+                        self._deleteScript(callbackId);
+                    };
+                }
+                this._createScript(callbackId, options.url);
+            },
+            _createScript: function (callbackId, url) {
+                var scriptu;
+                var scripto = document.getElementById('results' + callbackId);
+                scriptu = document.createElement('script');
+                scriptu.setAttribute('type', 'text/javascript');
+                scriptu.setAttribute('src', url);
+                scriptu.setAttribute('charset', 'UTF-8');
+                scriptu.setAttribute('id', 'results' + callbackId);
+                scriptu.setAttribute('async', 'true');
+                var node = document.documentElement || document.getElementsByTagName('head')[0];
+                if (scripto === null) {
+                    node.appendChild(scriptu);
+                } else {
+                    node.replaceChild(scriptu, scripto);
+                }
+            },
+            _deleteScript: function (callbackId) {
+                var script = document.getElementById('results' + callbackId);
+                if (script) {
+                    var node = script.parentNode || document.documentElement;
+                    if (!node) {
+                        return;
+                    }
+                    node.removeChild(script);
+                }
+            }
+        };
+        return JSONP;
+    }(UtilsLoggerByDefault);
+    ProtocolsProtocol = function (Helper, XHR, JSONP) {
+        var Protocol = {
+            send: function (options) {
+                var settings = options || {
+                    method: 'GET',
+                    protocol: 'JSONP',
+                    timeOut: 0,
+                    format: null,
+                    wrap: true,
+                    nocache: true,
+                    output: 'json',
+                    callback: null,
+                    callbackSuffix: null
+                };
+                if (options.protocol === 'XHR' || options.format === 'json') {
+                    settings.wrap = false;
+                } else if (options.protocol === 'JSONP' && options.format === 'xml') {
+                    settings.wrap = true;
+                }
+                settings.callback = options.protocol == 'JSONP' ? null : null;
+                settings.output = settings.wrap ? 'json' : null;
+                if (settings.wrap) {
+                    var params = {};
+                    params.output = settings.output;
+                    params.callback = settings.callback;
+                    delete params.callback;
+                    settings.url = Helper.normalyzeUrl(options.url, params);
+                }
+                switch (settings.protocol) {
+                case 'XHR':
+                    if (options.method === 'GET' && options.nocache) {
+                        settings.url = Helper.normalyzeUrl(settings.url, { t: new Date().getTime() });
+                    }
+                    XHR.call(settings);
+                    break;
+                case 'JSONP':
+                    if (settings.data) {
+                        settings.url = Helper.normalyzeUrl(settings.url, settings.data);
+                    }
+                    JSONP.call(settings);
+                    break;
+                default:
+                    throw new Error('protocol not supported (XHR|JSONP) !');
+                }
+            }
+        };
+        return Protocol;
+    }(UtilsHelper, ProtocolsXHR, ProtocolsJSONP);
+    ServicesDefaultUrlService = function () {
+        var protocol = location && location.protocol && location.protocol.indexOf('https:') === 0 ? 'https://' : 'http://';
+        var hostname = 'wxs.ign.fr';
+        var keyname = '%KEY%';
+        var url = protocol + hostname.concat('/', keyname);
+        var fkey = function (key) {
+            return this._key.replace(key ? keyname : null, key);
+        };
+        var DefaultUrlService = {
+            Alti: {
+                _key: {
+                    'elevation-json': url + '/alti/rest/elevation.json',
+                    'elevation-xml': url + '/alti/rest/elevation.xml',
+                    'profil-json': url + '/alti/rest/elevationLine.json',
+                    'profil-xml': url + '/alti/rest/elevationLine.xml',
+                    wps: url + '/alti/wps'
+                },
+                url: function (key) {
+                    return {
+                        'elevation-json': this._key['elevation-json'].replace(key ? keyname : null, key),
+                        'elevation-xml': this._key['elevation-xml'].replace(key ? keyname : null, key),
+                        'profil-json': this._key['profil-json'].replace(key ? keyname : null, key),
+                        'profil-xml': this._key['profil-xml'].replace(key ? keyname : null, key),
+                        wps: this._key.wps.replace(key ? keyname : null, key)
+                    };
+                }
+            },
+            ProcessIsoCurve: {
+                _key: {
+                    'iso-json': url + '/isochrone/isochrone.json',
+                    'iso-xml': url + '/isochrone/isochrone.xml'
+                },
+                url: function (key) {
+                    return {
+                        'iso-json': this._key['iso-json'].replace(key ? keyname : null, key),
+                        'iso-xml': this._key['iso-xml'].replace(key ? keyname : null, key)
+                    };
+                }
+            },
+            AutoComplete: {
+                _key: url + '/ols/apis/completion',
+                url: fkey
+            },
+            ReverseGeocode: {
+                _key: url + '/geoportail/ols',
+                url: fkey
+            },
+            AutoConf: {
+                _key: {
+                    apiKey: url + '/autoconf',
+                    apiKeys: url + '/autoconf?keys=%KEYS%'
+                },
+                url: function (key) {
+                    var keys = '';
+                    if (Array.isArray(key) && key.length > 0) {
+                        keys = key[0];
+                        for (var i = 1; i < key.length; i++) {
+                            keys += ',' + key[i];
+                        }
+                    }
+                    return {
+                        apiKey: this._key['apiKey'].replace(key ? keyname : null, key),
+                        apiKeys: this._key['apiKeys'].replace(keyname, key[0]).replace('%KEYS%', keys),
+                        aggregate: protocol + hostname.concat('/') + key + '/autoconf/id/'
+                    };
+                }
+            },
+            Geocode: {
+                _key: url + '/geoportail/ols',
+                url: fkey
+            },
+            Route: {
+                _key: {
+                    ols: url + '/itineraire/ols',
+                    'route-json': url + '/itineraire/rest/route.json',
+                    'route-xml': url + '/itineraire/rest/route.xml'
+                },
+                url: function (key) {
+                    return {
+                        ols: this._key.ols.replace(key ? keyname : null, key),
+                        'route-json': this._key['route-json'].replace(key ? keyname : null, key),
+                        'route-xml': this._key['route-xml'].replace(key ? keyname : null, key)
+                    };
+                }
+            }
+        };
+        return DefaultUrlService;
+    }();
+    ServicesCommonService = function (Logger, Helper, _, Protocol, ErrorService, DefaultUrlService) {
+        function CommonService(options) {
+            if (!(this instanceof CommonService)) {
+                throw new TypeError(_.getMessage('CLASS_CONSTRUCTOR'));
+            }
+            this.options = {
+                protocol: 'JSONP',
+                proxyURL: '',
+                callbackSuffix: null,
+                httpMethod: 'GET',
+                timeOut: 0,
+                rawResponse: false,
+                scope: this,
+                onSuccess: function (response) {
+                    console.log('onSuccess - la reponse est la suivante : ', response);
+                },
+                onFailure: function (error) {
+                    if (error.status === 200 || !error.status) {
+                        console.log('onFailure : ', error.message);
+                    } else {
+                        console.log('onFailure - Erreur (', error.status, ') : ', error.message);
+                    }
+                }
+            };
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+            if (!this.options.apiKey && !this.options.serverUrl) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'apiKey', 'serverUrl'));
+            }
+            if (this.options.rawResponse && !this.options.onSuccess) {
+                this.options.onSuccess = function (response) {
+                    console.log('onSuccess - la réponse brute du service est la suivante : ', response);
+                };
+            }
+            var bOnSuccess = this.options.onSuccess !== null && typeof this.options.onSuccess === 'function' ? true : false;
+            if (!bOnSuccess) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'onSuccess()'));
+            }
+            if (!this.options.serverUrl) {
+                var urlByDefault = DefaultUrlService[this.CLASSNAME].url(this.options.apiKey);
+                if (typeof urlByDefault === 'string') {
+                    this.options.serverUrl = urlByDefault;
+                } else {
+                }
+            }
+            if (this.options.serverUrl) {
+                var urlsource = this.options.serverUrl;
+                var urlparts = urlsource.split('?');
+                this.options.serverUrl = urlparts[0];
+            }
+            this.options.httpMethod = typeof options.httpMethod === 'string' ? options.httpMethod.toUpperCase() : 'GET';
+            switch (this.options.httpMethod) {
+            case 'POST':
+            case 'GET':
+                break;
+            case 'PUT':
+            case 'DELETE':
+            case 'HEAD':
+            case 'OPTIONS':
+                throw new Error(_.getMessage('PARAM_NOT_SUPPORT', 'httpMethod'));
+            default:
+                throw new Error(_.getMessage('PARAM_UNKNOWN', 'httpMethod'));
+            }
+            this.options.protocol = typeof options.protocol === 'string' ? options.protocol.toUpperCase() : 'JSONP';
+            switch (this.options.protocol) {
+            case 'JSONP':
+            case 'XHR':
+                break;
+            default:
+                throw new Error(_.getMessage('PARAM_UNKNOWN', 'protocol'));
+            }
+            if (this.options.protocol === 'JSONP') {
+                this.options.httpMethod = 'GET';
+            }
+            this.options.nocache = options.nocache || false;
+            this.options.outputFormat = null;
+            this.request = null;
+            this.response = null;
+        }
+        CommonService.prototype = {
+            constructor: CommonService,
+            call: function () {
+                function run() {
+                    this.buildRequest.call(this, onError, onBuildRequest);
+                }
+                run.call(this);
+                function onBuildRequest(result) {
+                    this.callService.call(this, onError, onCallService);
+                }
+                function onCallService(result) {
+                    this.analyzeResponse.call(this, onError, onAnalyzeResponse);
+                }
+                function onAnalyzeResponse(result) {
+                    if (result) {
+                        this.options.onSuccess.call(this, result);
+                    } else {
+                        return onError.call(this, new ErrorService('Analyse de la reponse en échec !?'));
+                    }
+                }
+                function onError(error) {
+                    var e = error;
+                    if (!(e instanceof ErrorService)) {
+                        e = new ErrorService(error.message);
+                    }
+                    this.options.onFailure.call(this, e);
+                }
+            },
+            buildRequest: function (error, success) {
+            },
+            callService: function (error, success) {
+                var strUrlProxified = null;
+                var strData = this.request;
+                var bUrlProxified = this.options.proxyURL && this.options.protocol === 'XHR' ? true : false;
+                this.options.serverUrl = Helper.normalyzeUrl(this.options.serverUrl, { 'gp-access-lib': '1.0.0-beta3' }, false);
+                if (bUrlProxified) {
+                    if (this.options.httpMethod === 'GET') {
+                        strUrlProxified = this.options.proxyURL + Helper.normalyzeUrl(this.options.serverUrl, this.request, true);
+                        strData = null;
+                    }
+                    if (this.options.httpMethod === 'POST') {
+                        strUrlProxified = this.options.proxyURL + Helper.normalyzeUrl(this.options.serverUrl, null, true);
+                        strData = this.request;
+                    }
+                }
+                var self = this;
+                var options = {
+                    url: strUrlProxified || this.options.serverUrl,
+                    method: this.options.httpMethod,
+                    protocol: this.options.protocol,
+                    timeOut: this.options.timeOut || 0,
+                    format: this.options.outputFormat,
+                    nocache: this.options.nocache || false,
+                    wrap: this.options.protocol === 'XHR' ? false : true,
+                    callbackSuffix: this.options.callbackSuffix,
+                    data: strData,
+                    headers: null,
+                    content: this.options.contentType || 'application/xml',
+                    scope: this.options.scope || this,
+                    onResponse: function (response) {
+                        var content = null;
+                        if (self.options.protocol == 'XHR') {
+                            content = response;
+                        }
+                        if (self.options.protocol == 'JSONP') {
+                            if (response) {
+                                if (response.http) {
+                                    if (response.http.status !== 200) {
+                                        error.call(self, new ErrorService({
+                                            status: response.http.status,
+                                            message: response.http.error,
+                                            type: ErrorService.TYPE_SRVERR
+                                        }));
+                                        return;
+                                    } else {
+                                        content = response.xml;
+                                    }
+                                } else {
+                                    content = response;
+                                }
+                            } else {
+                                error.call(self, new ErrorService('Le contenu de la reponse est vide !?'));
+                                return;
+                            }
+                        }
+                        self.response = content;
+                        success.call(self, content);
+                    },
+                    onFailure: function (e) {
+                        e.type = ErrorService.TYPE_SRVERR;
+                        error.call(self, new ErrorService(e));
+                    },
+                    onTimeOut: function () {
+                        error.call(self, new ErrorService('TimeOut!'));
+                    }
+                };
+                Protocol.send(options);
+            },
+            analyzeResponse: function (error, success) {
+            }
+        };
+        return CommonService;
+    }(UtilsLoggerByDefault, UtilsHelper, UtilsMessagesResources, ProtocolsProtocol, ExceptionsErrorService, ServicesDefaultUrlService);
+    ServicesAltiRequestModelAltiRequest = function (Logger) {
+        function AltiRequest(options) {
+            if (!(this instanceof AltiRequest)) {
+                throw new TypeError('AltiRequest constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            this.positions = this.options.positions || [];
+            this.delimiter = this.options.delimiter || '|';
+            this.indent = this.options.indent || false;
+            this.crs = this.options.crs || 'CRS:84';
+            this.format = this.options.format || 'json';
+        }
+        AltiRequest.CLASSNAME = 'AltiRequest';
+        AltiRequest.prototype = {
+            constructor: AltiRequest,
+            setPositions: function (lstPosition) {
+                var positions = [];
+                for (var i = 0; i < lstPosition.length; i++) {
+                    var o = lstPosition[i];
+                    if (o.lon && o.lat) {
+                        positions.push(o);
+                    }
+                }
+                this.positions = positions;
+            },
+            getPositions: function (pos) {
+                if (!pos) {
+                    return this.positions;
+                }
+                var index = this.positions.length - 1;
+                if (pos > index || pos < index) {
+                    return this.positions;
+                }
+                return this.positions[pos];
+            },
+            addPositions: function (lstPosition) {
+                for (var i = 0; i < lstPosition.length; i++) {
+                    var o = lstPosition[i];
+                    if (o.lon && o.lat) {
+                        this.positions.push(lstPosition[i]);
+                    }
+                }
+            },
+            getLon: function () {
+                var lstLon = [];
+                for (var i = 0; i < this.positions.length; i++) {
+                    lstLon.push(this.positions[i].lon);
+                }
+                return lstLon.join(this.delimiter);
+            },
+            getLat: function () {
+                var lstLat = [];
+                for (var i = 0; i < this.positions.length; i++) {
+                    lstLat.push(this.positions[i].lat);
+                }
+                return lstLat.join(this.delimiter);
+            }
+        };
+        AltiRequest.prototype.getData = function () {
+            var map = [];
+            map.push({
+                k: 'lon',
+                v: this.getLon()
+            });
+            map.push({
+                k: 'lat',
+                v: this.getLat()
+            });
+            map.push({
+                k: 'delimiter',
+                v: this.delimiter
+            });
+            map.push({
+                k: 'indent',
+                v: this.indent
+            });
+            map.push({
+                k: 'crs',
+                v: this.crs
+            });
+            map.push({
+                k: 'format',
+                v: this.format
+            });
+            return map;
+        };
+        return AltiRequest;
+    }(UtilsLoggerByDefault);
+    ServicesAltiRequestModelAltiElevationRequest = function (Logger, AltiRequest) {
+        function AltiElevationRequest(options) {
+            if (!(this instanceof AltiElevationRequest)) {
+                throw new TypeError('AltiElevationRequest constructor cannot be called as a function.');
+            }
+            this.CLASSNAME = 'AltiElevationRequest';
+            AltiRequest.apply(this, arguments);
+            this.zonly = this.options.zonly || false;
+        }
+        AltiElevationRequest.prototype = Object.create(AltiRequest.prototype, {
+            zonly: {
+                get: function () {
+                    return this._zonly;
+                },
+                set: function (z) {
+                    this._zonly = z;
+                }
+            }
+        });
+        AltiElevationRequest.prototype.constructor = AltiElevationRequest;
+        AltiElevationRequest.prototype.getData = function () {
+            var map = [];
+            map.push({
+                k: 'lon',
+                v: this.getLon()
+            });
+            map.push({
+                k: 'lat',
+                v: this.getLat()
+            });
+            map.push({
+                k: 'indent',
+                v: this.indent
+            });
+            map.push({
+                k: 'crs',
+                v: this.crs
+            });
+            map.push({
+                k: 'zonly',
+                v: this.zonly
+            });
+            map.push({
+                k: 'format',
+                v: this.format
+            });
+            return map;
+        };
+        return AltiElevationRequest;
+    }(UtilsLoggerByDefault, ServicesAltiRequestModelAltiRequest);
+    ServicesAltiRequestModelAltiProfilRequest = function (Logger, AltiRequest) {
+        function AltiProfilRequest(options) {
+            if (!(this instanceof AltiProfilRequest)) {
+                throw new TypeError('AltiProfilRequest constructor cannot be called as a function.');
+            }
+            this.CLASSNAME = 'AltiProfilRequest';
+            AltiRequest.apply(this, arguments);
+            this.sampling = this.options.sampling || 3;
+        }
+        AltiProfilRequest.prototype = Object.create(AltiRequest.prototype, {
+            sampling: {
+                get: function () {
+                    return this._sampling;
+                },
+                set: function (value) {
+                    this._sampling = value;
+                }
+            }
+        });
+        AltiProfilRequest.prototype.constructor = AltiProfilRequest;
+        AltiProfilRequest.prototype.getData = function () {
+            var map = [];
+            map.push({
+                k: 'lon',
+                v: this.getLon()
+            });
+            map.push({
+                k: 'lat',
+                v: this.getLat()
+            });
+            map.push({
+                k: 'indent',
+                v: this.indent
+            });
+            map.push({
+                k: 'crs',
+                v: this.crs
+            });
+            map.push({
+                k: 'sampling',
+                v: this.sampling
+            });
+            map.push({
+                k: 'format',
+                v: this.format
+            });
+            return map;
+        };
+        return AltiProfilRequest;
+    }(UtilsLoggerByDefault, ServicesAltiRequestModelAltiRequest);
+    ServicesAltiRequestAltiRequestREST = function (Logger, _, AltiElevationRequest, AltiProfilRequest) {
+        function AltiRequestREST(options) {
+            if (!(this instanceof AltiRequestREST)) {
+                throw new TypeError('AltiRequestREST constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            if (!this.options) {
+                throw new Error(_.getMessage('PARAM_EMPTY', 'options'));
+            }
+            if (!this.options.type) {
+                throw new Error(_.getMessage('PARAM_EMPTY', 'type (Elevation or Profil)'));
+            }
+            this.DataObject = null;
+            switch (this.options.type) {
+            case 'Elevation':
+                this.DataObject = new AltiElevationRequest(this.options.param);
+                break;
+            case 'Profil':
+                this.DataObject = new AltiProfilRequest(this.options.param);
+                break;
+            default:
+                throw new Error(_.getMessage('PARAM_TYPE', 'type (Elevation or Profil)'));
+            }
+            this.method = this.options.method || 'GET';
+        }
+        AltiRequestREST.prototype = {
+            requestString: null,
+            constructor: AltiRequestREST,
+            template: {
+                get: {
+                    value: 'lon=__LON__&lat=__LAT__&indent=__INDENT__&crs=\'__CRS__\'',
+                    input: {
+                        point: '&zonly=__ZONLY__',
+                        profil: '&sampling=__SAMPLING__'
+                    }
+                },
+                post: {
+                    value: 'lon=__LON__\n' + 'lat=__LAT__\n' + 'indent=__INDENT__\n' + 'crs=\'__CRS__\'\n',
+                    input: {
+                        point: 'zonly=__ZONLY__',
+                        profil: 'sampling=__SAMPLING__'
+                    }
+                }
+            },
+            processRequestString: function () {
+                var template = '';
+                if (this.method == 'POST') {
+                    template = this.template.post.value;
+                } else if (this.method == 'GET') {
+                    template = this.template.get.value;
+                }
+                template = template.replace(/__LON__/g, this.DataObject.getLon());
+                template = template.replace(/__LAT__/g, this.DataObject.getLat());
+                template = template.replace(/__INDENT__/g, this.DataObject.indent);
+                template = template.replace(/__CRS__/g, this.DataObject.crs);
+                template = template + this.__addDataInputs();
+                this.requestString = template;
+                return this.requestString;
+            },
+            __addDataInputs: function () {
+                var myTemplate;
+                if (this.method == 'POST') {
+                    myTemplate = this.template.post;
+                } else if (this.method == 'GET') {
+                    myTemplate = this.template.get;
+                } else {
+                    throw new Error('No other HTTP method supported by the service !');
+                }
+                var tmpl = null;
+                if (this.DataObject.CLASSNAME == 'AltiElevationRequest') {
+                    tmpl = myTemplate.input.point;
+                    return tmpl.replace(/__ZONLY__/g, this.DataObject.zonly);
+                } else if (this.DataObject.CLASSNAME == 'AltiProfilRequest') {
+                    tmpl = myTemplate.input.profil;
+                    return tmpl.replace(/__SAMPLING__/g, this.DataObject.sampling);
+                } else {
+                    throw new Error('No other object supported than elevation or profil !?');
+                }
+            }
+        };
+        return AltiRequestREST;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ServicesAltiRequestModelAltiElevationRequest, ServicesAltiRequestModelAltiProfilRequest);
+    FormatsWPS = function (Logger) {
+        function WPS(options) {
+            if (!(this instanceof WPS)) {
+                throw new TypeError('WPS constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            this.DataObject = this.options.data;
+            if (!this.DataObject) {
+                throw new TypeError('This data object is not defined !');
+            }
+            this.paramservice = this.options.param.service || 'WPS';
+            this.paramversion = this.options.param.version || '1.0.0';
+            this.paramidentifier = this.options.param.identifier || 'gs:WPS';
+            this.paramrawdataoutput = this.options.param.rawdataoutput || 'result';
+            this.paramrequest = this.options.param.request || 'Execute';
+            this.method = this.options.method || 'GET';
+        }
+        WPS.prototype = {
+            requestString: null,
+            constructor: WPS,
+            template: {
+                get: {
+                    value: 'service=__SERVICE__' + '&version=__VERSION__' + '&rawdataoutput=__RAWDATAOUTPUT__' + '&identifier=__IDENTIFIER__' + '&request=__REQUEST__' + '&datainputs=<!-- __DATAINPUTS__ -->',
+                    input: '__KEY__=__DATA__'
+                },
+                post: {
+                    value: '<?xml version="1.0" encoding="UTF-8"?>' + '<wps:__REQUEST__ version="__VERSION__" service="__SERVICE__" ' + '__NAMESPACE__ __SCHEMALOCATION__>' + '<ows:Identifier>__IDENTIFIER__</ows:Identifier>' + '<wps:DataInputs>' + '<!-- __DATAINPUTS__ -->' + '</wps:DataInputs>' + '<wps:ResponseForm>' + '<wps:RawDataOutput>' + '<ows:Identifier>__RAWDATAOUTPUT__</ows:Identifier>' + '</wps:RawDataOutput>' + '</wps:ResponseForm>' + '</wps:__REQUEST__>',
+                    input: '<wps:Input>' + '<ows:Identifier>__KEY__</ows:Identifier>' + '<wps:Data>' + '<wps:LiteralData>__DATA__</wps:LiteralData>' + '</wps:Data>' + '</wps:Input>'
+                }
+            },
+            namespaceByDefault: function () {
+                var ns = [
+                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',
+                    'xmlns="http://www.opengis.net/wps/1.0.0"',
+                    'xmlns:wfs="http://www.opengis.net/wfs"',
+                    'xmlns:wps="http://www.opengis.net/wps/1.0.0"',
+                    'xmlns:ows="http://www.opengis.net/ows/1.1"',
+                    'xmlns:gml="http://www.opengis.net/gml"',
+                    'xmlns:ogc="http://www.opengis.net/ogc"',
+                    'xmlns:wcs="http://www.opengis.net/wcs/1.1.1"',
+                    'xmlns:xlink="http://www.w3.org/1999/xlink"'
+                ];
+                return ns.join(' ');
+            },
+            schemaLocationByDefault: function () {
+                return 'xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd"';
+            },
+            processRequestString: function () {
+                var template = '';
+                if (this.method == 'POST') {
+                    template = this.template.post.value;
+                } else if (this.method == 'GET') {
+                    template = this.template.get.value;
+                } else {
+                    return false;
+                }
+                template = template.replace(/__SERVICE__/g, this.paramservice);
+                template = template.replace(/__VERSION__/g, this.paramversion);
+                template = template.replace(/__RAWDATAOUTPUT__/g, this.paramrawdataoutput);
+                template = template.replace(/__IDENTIFIER__/g, this.paramidentifier);
+                template = template.replace(/__REQUEST__/g, this.paramrequest);
+                if (this.method == 'POST') {
+                    template = template.replace(/__NAMESPACE__/g, this.namespaceByDefault);
+                    template = template.replace(/__SCHEMALOCATION__/g, this.schemaLocationByDefault);
+                }
+                template = template.replace(/<!-- __DATAINPUTS__ -->/g, this.__addDataInputs());
+                if (!template) {
+                    return false;
+                }
+                this.requestString = template;
+                return true;
+            },
+            __addDataInputs: function () {
+                var tmpl = this.method == 'GET' ? this.template.get.input : this.template.post.input;
+                var sep = this.method == 'GET' ? ';' : '';
+                var result = '';
+                var that = this;
+                var map = this.DataObject.getData();
+                for (var i = 0; i < map.length; i++) {
+                    (function (j) {
+                        if (sep) {
+                            sep = j == map.length - 1 ? '' : ';';
+                        }
+                        result = result.concat(that.__addDataInput(tmpl, map[j].k, map[j].v), sep);
+                    }(i));
+                }
+                return result;
+            },
+            __addDataInput: function (tmpl, key, data) {
+                var tmp = tmpl;
+                tmp = tmp.replace(/__KEY__/g, key);
+                tmp = tmp.replace(/__DATA__/g, data);
+                return tmp;
+            },
+            setMethod: function (method) {
+                if (method == 'GET' || method == 'POST') {
+                    this.method = method;
+                } else {
+                }
+            },
+            getMethod: function () {
+                return this.method;
+            }
+        };
+        return WPS;
+    }(UtilsLoggerByDefault);
+    ServicesAltiRequestAltiRequestWPS = function (Logger, _, WPS, AltiElevationRequest, AltiProfilRequest) {
+        var AltiRequestWPS = {
+            build: function (options) {
+                if (!options) {
+                    throw new Error(_.getMessage('PARAM_EMPTY', 'options'));
+                }
+                if (!options.type) {
+                    throw new Error(_.getMessage('PARAM_EMPTY', 'type (Elevation or Profil)'));
+                }
+                var DataObject = null;
+                switch (options.type) {
+                case 'Elevation':
+                    options.wps.identifier = 'gs:WPSElevation';
+                    DataObject = new AltiElevationRequest(options.param);
+                    break;
+                case 'Profil':
+                    options.wps.identifier = 'gs:WPSLineElevation';
+                    DataObject = new AltiProfilRequest(options.param);
+                    break;
+                default:
+                    throw new Error(_.getMessage('PARAM_TYPE', 'type (Elevation or Profil)'));
+                }
+                var settings = {
+                    data: DataObject,
+                    method: options.method,
+                    param: options.wps
+                };
+                var rqstWPS = new WPS(settings);
+                if (!rqstWPS.processRequestString()) {
+                    throw new Error('Enable to process request !');
+                }
+                return rqstWPS.requestString;
+            }
+        };
+        return AltiRequestWPS;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, FormatsWPS, ServicesAltiRequestModelAltiElevationRequest, ServicesAltiRequestModelAltiProfilRequest);
+    ServicesAltiRequestAltiRequestFactory = function (Logger, ErrorService, AltiRequestREST, AltiRequestWPS) {
+        var AltiRequestFactory = {
+            build: function (options) {
+                var request = null;
+                var settings = {
+                    type: options.sampling ? 'Profil' : 'Elevation',
+                    method: options.httpMethod,
+                    param: {
+                        positions: null,
+                        delimiter: null,
+                        indent: null,
+                        crs: null,
+                        format: null,
+                        sampling: null,
+                        zonly: null
+                    }
+                };
+                settings.param.positions = options.positions;
+                settings.param.format = options.outputFormat;
+                settings.param.sampling = options.sampling;
+                settings.param.zonly = options.zonly;
+                var bOnError = options.onError !== null && typeof options.onError === 'function' ? true : false;
+                var bOnSuccess = options.onSuccess !== null && typeof options.onSuccess === 'function' ? true : false;
+                var message = null;
+                switch (options.api) {
+                case 'REST':
+                    var myReq = new AltiRequestREST(settings);
+                    if (!myReq.processRequestString()) {
+                        message = 'Error in process request (rest) !';
+                        if (bOnError) {
+                            options.onError.call(options.scope, new ErrorService(message));
+                            return;
+                        }
+                        throw new Error(message);
+                    }
+                    request = myReq.requestString;
+                    break;
+                case 'WPS':
+                    settings.wps = {
+                        service: null,
+                        version: null,
+                        identifier: null,
+                        rawdataoutput: null,
+                        request: null
+                    };
+                    request = AltiRequestWPS.build(settings);
+                    if (!request) {
+                        message = 'Error in process request (wps) !';
+                        if (bOnError) {
+                            options.onError.call(options.scope, new ErrorService(message));
+                            return;
+                        }
+                        throw new Error(message);
+                    }
+                    break;
+                default:
+                    message = 'Type of API is not supported by service (REST or WPS) !';
+                    if (bOnError) {
+                        options.onError.call(options.scope, new ErrorService(message));
+                        return;
+                    }
+                    throw new Error(message);
+                }
+                if (bOnSuccess) {
+                    options.onSuccess.call(options.scope, request);
+                }
+                return request;
+            }
+        };
+        return AltiRequestFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, ServicesAltiRequestAltiRequestREST, ServicesAltiRequestAltiRequestWPS);
+    FormatsXML = function (Logger) {
+        function XML(options) {
+            if (!(this instanceof XML)) {
+                throw new TypeError('XML constructor cannot be called as a function.');
+            }
+            this.xmlString = null;
+            this.xmlDoc = null;
+            this.reader = null;
+            if (options) {
+                if (options.xmlString && typeof options.xmlString === 'string') {
+                    this.xmlString = options.xmlString;
+                    this.xmlDoc = __getXMLDOC(options.xmlString);
+                }
+                if (options.reader) {
+                    this.setReader(options.reader);
+                }
+            }
+        }
+        XML.prototype = {
+            constructor: XML,
+            getXMLString: function () {
+                return this.xmlString;
+            },
+            setXMLString: function (xmlString) {
+                if (xmlString && typeof xmlString === 'string') {
+                    this.xmlString = xmlString;
+                    this.xmlDoc = __getXMLDOC(xmlString);
+                }
+            },
+            getReader: function () {
+                return this.reader;
+            },
+            setReader: function (reader) {
+                if (reader && reader.read && typeof reader.read === 'function') {
+                    this.reader = reader;
+                }
+            },
+            getXMLDoc: function () {
+                return this.xmlDoc;
+            },
+            setXMLDoc: function (doc) {
+                this.xmlDoc = doc;
+            },
+            parse: function () {
+                if (!this.xmlDoc && this.xmlString) {
+                    this.xmlDoc = __getXMLDOC(this.xmlString);
+                }
+                if (this.xmlDoc) {
+                    var root = __getRootNode(this.xmlDoc);
+                    if (root) {
+                        var parserOutput;
+                        if (this.reader && this.reader.read) {
+                            parserOutput = this.reader.read(root);
+                        } else {
+                            parserOutput = {};
+                            parserOutput[root.nodeName] = __readDefault(root);
+                        }
+                        return parserOutput;
+                    } else {
+                        return {};
+                    }
+                }
+            }
+        };
+        function __getXMLDOC(xmlString) {
+            if (typeof exports === 'object') {
+                var DOMParser = xmldom.DOMParser;
+                return new DOMParser().parseFromString(xmlString, 'text/xml');
+            } else {
+                var parser;
+                var xmlDoc;
+                var errorMsg = 'Erreur lors du parsing de la réponse du service : XML non conforme';
+                if (window.ActiveXObject) {
+                    xmlDoc = new window.ActiveXObject('Microsoft.XMLDOM');
+                    xmlDoc.async = false;
+                    xmlDoc.loadXML(xmlString);
+                    var parseError = xmlDoc.parseError;
+                    if (parseError.errorCode) {
+                        if (parseError.line && parseError.linepos) {
+                            errorMsg += '( ligne ' + parseError.line + ', colonne ' + parseError.linepos;
+                        }
+                        if (parseError.reason) {
+                            errorMsg += ':  ' + parseError.reason + ')';
+                        }
+                        throw new Error(errorMsg);
+                    }
+                    return xmlDoc;
+                } else if (window.DOMParser) {
+                    parser = new window.DOMParser();
+                    try {
+                        xmlDoc = parser.parseFromString(xmlString, 'text/xml');
+                    } catch (e) {
+                        if (e.message === 'SyntaxError') {
+                            throw new Error(errorMsg);
+                        } else {
+                            throw new Error('Erreur lors du parsing de la réponse du service : ' + e.message);
+                        }
+                    }
+                    if (xmlDoc.getElementsByTagName('parsererror').length > 0) {
+                        var parsererror = xmlDoc.getElementsByTagName('parsererror');
+                        for (var i = 0; i < parsererror.length; i++) {
+                            var content = parsererror[i].innerHTML;
+                            if (content.indexOf('Huge input lookup') == -1) {
+                                errorMsg += '(' + content + ')';
+                                throw new Error(errorMsg);
+                            }
+                        }
+                    } else if (!xmlDoc.documentElement) {
+                        throw new Error(errorMsg);
+                    }
+                    return xmlDoc;
+                } else {
+                    throw new Error('Incompatible DOM Parser pour ce navigateur !');
+                }
+            }
+        }
+        function __getRootNode(xmlDoc) {
+            var root;
+            if (xmlDoc.nodeType === 9) {
+                root = xmlDoc.documentElement;
+            } else if (xmlDoc.nodeType === 1) {
+                root = xmlDoc;
+            }
+            return root;
+        }
+        function __readDefault(node) {
+            var data = {};
+            if (node.attributes.length > 0) {
+                var dataAttributes = __getAttributes(node);
+                data['attributes'] = dataAttributes;
+            }
+            if (node.hasChildNodes()) {
+                var childData = {};
+                var child;
+                var children = node.childNodes;
+                for (var i = 0; i < children.length; i++) {
+                    child = children[i];
+                    if (child.nodeType === 3) {
+                        data['textContent'] = child.nodeValue;
+                    } else if (child.nodeType === 1) {
+                        childData = __readDefault(child);
+                        if (!data[child.nodeName]) {
+                            data[child.nodeName] = childData;
+                        } else {
+                            if (!Array.isArray(data[child.nodeName])) {
+                                var old = data[child.nodeName];
+                                data[child.nodeName] = [];
+                                data[child.nodeName].push(old);
+                            }
+                            data[child.nodeName].push(childData);
+                        }
+                    }
+                }
+            }
+            return data;
+        }
+        function __getAttributes(node) {
+            if (node.attributes.length > 0) {
+                var nodeAttributes = {};
+                var attributes = node.attributes;
+                for (var i = 0; i < attributes.length; i++) {
+                    var attribute = attributes[i];
+                    nodeAttributes[attribute.nodeName] = attribute.nodeValue;
+                }
+                return nodeAttributes;
+            }
+        }
+        return XML;
+    }(UtilsLoggerByDefault);
+    ServicesAltiResponseModelAltiResponse = function () {
+        function AltiResponse() {
+            if (!(this instanceof AltiResponse)) {
+                throw new TypeError('AltiResponse constructor cannot be called as a function.');
+            }
+            this.elevations = [];
+        }
+        AltiResponse.prototype = { constructor: AltiResponse };
+        return AltiResponse;
+    }();
+    ServicesAltiResponseModelElevation = function () {
+        function Elevation() {
+            if (!(this instanceof Elevation)) {
+                throw new TypeError('Elevation constructor cannot be called as a function.');
+            }
+            this.z = null;
+        }
+        Elevation.prototype = { constructor: Elevation };
+        return Elevation;
+    }();
+    ServicesAltiFormatsAltiResponseReader = function (Logger, AltiResponse, Elevation) {
+        var AltiResponseReader = {};
+        AltiResponseReader.READERS = {
+            elevations: function (root) {
+                var altiResponse = new AltiResponse();
+                if (root.hasChildNodes()) {
+                    var children = root.childNodes;
+                    var child;
+                    var elevation;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (AltiResponseReader.READERS[child.nodeName]) {
+                            elevation = AltiResponseReader.READERS[child.nodeName](child);
+                            altiResponse.elevations.push(elevation);
+                        }
+                    }
+                }
+                return altiResponse;
+            },
+            elevation: function (node) {
+                var elevation = new Elevation();
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (AltiResponseReader.READERS[child.nodeName]) {
+                            AltiResponseReader.READERS[child.nodeName](child, elevation);
+                        }
+                    }
+                }
+                return elevation;
+            },
+            lat: function (node, elevation) {
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    elevation.lat = parseFloat(textNode.nodeValue);
+                } else {
+                    throw new Error('Erreur dans la lecture de la réponse du service: latitude attendue mais absente');
+                }
+            },
+            lon: function (node, elevation) {
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    elevation.lon = parseFloat(textNode.nodeValue);
+                } else {
+                    throw new Error('Erreur dans la lecture de la réponse du service: longitude attendue mais absente');
+                }
+            },
+            z: function (node, elevation) {
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    if (elevation) {
+                        elevation.z = parseFloat(textNode.nodeValue);
+                    } else {
+                        elevation = new Elevation();
+                        elevation.z = parseFloat(textNode.nodeValue);
+                        return elevation;
+                    }
+                } else {
+                    throw new Error('Erreur dans la lecture de la réponse du service: altitude attendue mais absente');
+                }
+            },
+            acc: function (node, elevation) {
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    elevation.acc = parseFloat(textNode.nodeValue);
+                } else {
+                    throw new Error('Erreur dans la lecture de la réponse du service: précision (acc) attendue mais absente');
+                }
+            },
+            exceptionreport: function (node) {
+                var response = {};
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (child.nodeName === 'Exception') {
+                            response.exceptionReport = AltiResponseReader.READERS.exception(child);
+                        }
+                    }
+                }
+                return response;
+            },
+            exception: function (node) {
+                var exceptionReport = {};
+                var exceptionCode = node.getAttribute('exceptionCode');
+                if (exceptionCode) {
+                    exceptionReport.exceptionCode = exceptionCode;
+                }
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    exceptionReport.exception = textNode.nodeValue;
+                }
+                return exceptionReport;
+            },
+            error: function (node) {
+                var response = { error: {} };
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        var textNode;
+                        if (child.nodeType === 1 && child.nodeName === 'code') {
+                            textNode = child.firstChild;
+                            if (textNode && textNode.nodeType === 3) {
+                                response.error.code = textNode.nodeValue;
+                            }
+                        }
+                        if (child.nodeType === 1 && child.nodeName === 'description') {
+                            textNode = child.firstChild;
+                            if (textNode && textNode.nodeType === 3) {
+                                response.error.description = textNode.nodeValue;
+                            }
+                        }
+                    }
+                }
+                return response;
+            }
+        };
+        AltiResponseReader.read = function (root) {
+            if (root.nodeName === 'elevations') {
+                var altiResponse = AltiResponseReader.READERS.elevations(root);
+                return altiResponse;
+            } else if (root.nodeName === 'ExceptionReport') {
+                var exceptionReport = AltiResponseReader.READERS.exceptionreport(root);
+                return exceptionReport;
+            } else if (root.nodeName === 'error') {
+                var error = AltiResponseReader.READERS.error(root);
+                return error;
+            } else {
+                throw new Error('Erreur lors de la lecture de la réponse : elle n\'est pas au format attendu.');
+            }
+        };
+        return AltiResponseReader;
+    }(UtilsLoggerByDefault, ServicesAltiResponseModelAltiResponse, ServicesAltiResponseModelElevation);
+    ServicesAltiResponseAltiResponseFactory = function (Logger, ErrorService, MRes, XML, AltiResponseReader, AltiResponse, Elevation) {
+        var AltiResponseFactory = {
+            build: function (options) {
+                var data = null;
+                if (options.response) {
+                    if (options.rawResponse) {
+                        data = options.response;
+                    } else {
+                        switch (options.outputFormat) {
+                        case 'xml':
+                            try {
+                                var p = new XML({ reader: AltiResponseReader });
+                                if (typeof options.response === 'string') {
+                                    p.setXMLString(options.response);
+                                } else {
+                                    p.setXMLDoc(options.response);
+                                }
+                                data = p.parse();
+                                if (!data) {
+                                    throw new Error(MRes.getMessage('SERVICE_RESPONSE_EXCEPTION_2'));
+                                }
+                            } catch (e) {
+                                var message = e.message;
+                                options.onError.call(options.scope, new ErrorService({
+                                    message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', message),
+                                    status: 200,
+                                    type: ErrorService.TYPE_SRVERR
+                                }));
+                                return;
+                            }
+                            break;
+                        case 'json':
+                            var JSONResponse;
+                            if (typeof options.response === 'string') {
+                                JSONResponse = window.JSON.parse(options.response);
+                            } else {
+                                JSONResponse = options.response;
+                            }
+                            if (JSONResponse.error) {
+                                options.onError.call(options.scope, new ErrorService({
+                                    message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', JSONResponse.error.description),
+                                    status: 200,
+                                    type: ErrorService.TYPE_SRVERR
+                                }));
+                                return;
+                            }
+                            if (JSONResponse) {
+                                var elevations = JSONResponse.elevations;
+                                var altiResponse = new AltiResponse();
+                                var elevation;
+                                if (Array.isArray(elevations) && elevations.length) {
+                                    for (var i = 0; i < elevations.length; i++) {
+                                        elevation = new Elevation();
+                                        if (typeof elevations[i] === 'object') {
+                                            if (elevations[i].lon) {
+                                                elevation.lon = elevations[i].lon;
+                                            }
+                                            if (elevations[i].lat) {
+                                                elevation.lat = elevations[i].lat;
+                                            }
+                                            if (elevations[i].z) {
+                                                elevation.z = elevations[i].z;
+                                            }
+                                            if (elevations[i].acc) {
+                                                elevation.acc = elevations[i].acc;
+                                            }
+                                        } else if (typeof elevations[i] === 'number') {
+                                            elevation.z = elevations[i];
+                                        }
+                                        if (Array.isArray(altiResponse.elevations)) {
+                                            altiResponse.elevations.push(elevation);
+                                        }
+                                    }
+                                }
+                                data = altiResponse;
+                            }
+                            if (!data) {
+                                options.onError.call(options.scope, new ErrorService({
+                                    message: MRes.getMessage('SERVICE_RESPONSE_ANALYSE_2'),
+                                    type: ErrorService.TYPE_UNKERR,
+                                    status: -1
+                                }));
+                                return;
+                            }
+                            break;
+                        default:
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_FORMAT_2'),
+                                type: ErrorService.TYPE_UNKERR,
+                                status: -1
+                            }));
+                            return;
+                        }
+                        if (data.exceptionReport) {
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', data.exceptionReport),
+                                type: ErrorService.TYPE_SRVERR,
+                                status: 200
+                            }));
+                            return;
+                        } else if (data.error) {
+                            var errorMess = data.error.description;
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', errorMess),
+                                type: ErrorService.TYPE_SRVERR,
+                                status: 200
+                            }));
+                            return;
+                        }
+                    }
+                } else {
+                    options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EMPTY')));
+                    return;
+                }
+                options.onSuccess.call(options.scope, data);
+                return;
+            }
+        };
+        return AltiResponseFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, UtilsMessagesResources, FormatsXML, ServicesAltiFormatsAltiResponseReader, ServicesAltiResponseModelAltiResponse, ServicesAltiResponseModelElevation);
+    ServicesAltiAlti = function (Logger, _, ErrorService, CommonService, DefaultUrlService, AltiRequestFactory, AltiResponseFactory) {
+        function Alti(options) {
+            if (!(this instanceof Alti)) {
+                throw new TypeError(_.getMessage('CLASS_CONSTRUCTOR', 'Alti'));
+            }
+            this.CLASSNAME = 'Alti';
+            CommonService.apply(this, arguments);
+            if (!options.positions) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'positions'));
+            }
+            if (options.positions.length === 0) {
+                throw new Error(_.getMessage('PARAM_EMPTY', 'positions'));
+            }
+            this.options.positions = options.positions;
+            this.options.outputFormat = typeof options.outputFormat === 'string' ? options.outputFormat.toLowerCase() : 'xml';
+            this.options.sampling = options.sampling || null;
+            this.options.api = typeof options.api === 'string' ? options.api.toUpperCase() : 'REST';
+            if (this.options.api === 'REST') {
+                this.options.httpMethod = 'GET';
+            }
+            this.options.zonly = options.zonly || false;
+            if (!this.options.serverUrl) {
+                var lstUrlByDefault = DefaultUrlService.Alti.url(this.options.apiKey);
+                var urlFound = null;
+                switch (this.options.api) {
+                case 'WPS':
+                    urlFound = lstUrlByDefault.wps;
+                    break;
+                case 'REST':
+                    var key = (options.sampling ? 'profil' : 'elevation') + '-' + this.options.outputFormat;
+                    urlFound = lstUrlByDefault[key];
+                    break;
+                default:
+                    throw new Error(_.getMessage('PARAM_UNKNOWN', 'api'));
+                }
+                if (!urlFound) {
+                    throw new Error('Url by default not found !');
+                }
+                this.options.serverUrl = urlFound;
+            }
+            var idx = this.options.serverUrl.lastIndexOf('.');
+            if (idx !== -1) {
+                var extension = this.options.serverUrl.substring(idx + 1);
+                if (extension && extension.length < 5) {
+                    switch (extension.toLowerCase()) {
+                    case 'json':
+                    case 'xml':
+                        this.options.outputFormat = extension.toLowerCase();
+                        break;
+                    default:
+                        throw new Error('type of service : unknown or unsupported (json or xml) !');
+                    }
+                }
+            }
+        }
+        Alti.prototype = Object.create(CommonService.prototype, {});
+        Alti.prototype.constructor = Alti;
+        Alti.prototype.buildRequest = function (error, success) {
+            var options = {
+                httpMethod: this.options.httpMethod,
+                onSuccess: function (result) {
+                    this.request = result;
+                    success.call(this, this.request);
+                },
+                onError: error,
+                scope: this,
+                positions: this.options.positions,
+                outputFormat: this.options.outputFormat,
+                sampling: this.options.sampling,
+                api: this.options.api,
+                zonly: this.options.zonly
+            };
+            AltiRequestFactory.build(options);
+        };
+        Alti.prototype.analyzeResponse = function (error, success) {
+            if (this.response) {
+                var options = {
+                    response: this.response,
+                    outputFormat: this.options.outputFormat,
+                    rawResponse: this.options.rawResponse,
+                    onError: error,
+                    onSuccess: success,
+                    scope: this
+                };
+                AltiResponseFactory.build(options);
+            } else {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_RESPONSE_EMPTY')));
+            }
+        };
+        return Alti;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, ServicesCommonService, ServicesDefaultUrlService, ServicesAltiRequestAltiRequestFactory, ServicesAltiResponseAltiResponseFactory);
+    ServicesAutoConfResponseModelAutoConfResponse = function () {
+        function AutoConfResponse() {
+            if (!(this instanceof AutoConfResponse)) {
+                throw new TypeError('AutoConfResponse constructor cannot be called as a function.');
+            }
+            this.generalOptions = {
+                apiKeys: {},
+                title: null,
+                defaultGMLGFIStyle: null,
+                theme: null,
+                wgs84Resolutions: []
+            };
+            this.layers = {};
+            this.territories = {};
+            this.tileMatrixSets = {};
+            this.services = {};
+        }
+        AutoConfResponse.prototype = {
+            constructor: AutoConfResponse,
+            isConfLoaded: function (apiKey) {
+                if (!apiKey) {
+                    return;
+                }
+                if (this.generalOptions.apiKeys[apiKey]) {
+                    return true;
+                }
+                return false;
+            },
+            getLayersId: function (apiKey) {
+                return this.generalOptions.apiKeys[apiKey];
+            },
+            getLayersConf: function (apiKey) {
+                var layers = {};
+                var layersIdArray = this.getLayersId(apiKey);
+                if (layersIdArray) {
+                    for (var i = 0; i < layersIdArray.length; i++) {
+                        var lyrId = layersIdArray[i];
+                        layers[lyrId] = this.layers[lyrId];
+                    }
+                }
+                return layers;
+            },
+            getLayerConf: function (layerId) {
+                if (!this.layers) {
+                    return;
+                }
+                return this.layers[layerId];
+            },
+            getTileMatrixSets: function () {
+                return this.tileMatrixSets;
+            },
+            getTMSConf: function (tmsID) {
+                if (!this.tileMatrixSets) {
+                    return;
+                }
+                return this.tileMatrixSets[tmsID];
+            },
+            getTerritories: function () {
+                return this.territories;
+            },
+            getTerritoryConf: function (territoryID) {
+                if (!this.territories) {
+                    return;
+                }
+                return this.territories[territoryID];
+            },
+            getServices: function () {
+                return this.services;
+            },
+            getServiceConf: function (serviceID) {
+                if (!this.services) {
+                    return;
+                }
+                return this.services[serviceID];
+            }
+        };
+        return AutoConfResponse;
+    }();
+    ServicesAutoConfResponseModelConstraint = function () {
+        function Constraint() {
+            if (!(this instanceof Constraint)) {
+                throw new TypeError('Constraint constructor cannot be called as a function.');
+            }
+            this.crs = null;
+            this.bbox = {
+                left: null,
+                right: null,
+                top: null,
+                bottom: null
+            };
+            this.minScaleDenominator = null;
+            this.maxScaleDenominator = null;
+            this.temporalExtent = [
+                null,
+                null
+            ];
+        }
+        Constraint.prototype = { constructor: Constraint };
+        return Constraint;
+    }();
+    ServicesAutoConfResponseModelFormat = function () {
+        function Format() {
+            if (!(this instanceof Format)) {
+                throw new TypeError('Format constructor cannot be called as a function.');
+            }
+            this.current = null;
+            this.name = null;
+        }
+        Format.prototype = { constructor: Format };
+        return Format;
+    }();
+    ServicesAutoConfResponseModelLayer = function () {
+        function Layer() {
+            if (!(this instanceof Layer)) {
+                throw new TypeError('Layer constructor cannot be called as a function.');
+            }
+        }
+        Layer.prototype = {
+            constructor: Layer,
+            getName: function () {
+                return this.name;
+            },
+            getTitle: function () {
+                return this.title;
+            },
+            getDescription: function () {
+                return this.description;
+            },
+            getLayerId: function () {
+                return this.layerId;
+            },
+            getQuicklookUrl: function () {
+                return this.quicklookUrl;
+            },
+            getDefaultProjection: function () {
+                return this.defaultProjection;
+            },
+            getProjections: function () {
+                var projections = [];
+                projections.push(this.defaultProjection);
+                var proj = projections.concat(this.additionalProjections);
+                return proj;
+            },
+            getBBOX: function () {
+                if (!this.globalConstraint) {
+                    return;
+                }
+                return this.globalConstraint.bbox;
+            },
+            getMinScaleDenominator: function () {
+                if (!this.globalConstraint) {
+                    return;
+                }
+                return this.globalConstraint.minScaleDenominator;
+            },
+            getMaxScaleDenominator: function () {
+                if (!this.globalConstraint) {
+                    return;
+                }
+                return this.globalConstraint.maxScaleDenominator;
+            },
+            getTMSID: function () {
+                if (this.wmtsOptions) {
+                    return this.wmtsOptions.tileMatrixSetLink;
+                }
+                return;
+            },
+            getServiceParams: function () {
+                return this.serviceParams;
+            },
+            getServerUrl: function (apiKey) {
+                if (!apiKey || !this.serviceParams || !this.serviceParams.serverUrl) {
+                    return;
+                }
+                return this.serviceParams.serverUrl[apiKey];
+            },
+            getLegends: function () {
+                return this.legends;
+            },
+            getMetadata: function () {
+                return this.metadata;
+            },
+            getStyles: function () {
+                return this.styles;
+            },
+            getDefaultStyle: function () {
+                if (!this.styles) {
+                    return;
+                }
+                var style;
+                var s = this.styles;
+                for (var i = 0; i < s.length; i++) {
+                    if (s[i].current === true) {
+                        style = s[i].name;
+                        break;
+                    }
+                }
+                return style;
+            },
+            getThematics: function () {
+                return this.thematics;
+            },
+            getDefaultFormat: function () {
+                if (!this.formats) {
+                    return;
+                }
+                var format;
+                var f = this.formats;
+                for (var i = 0; i < f.length; i++) {
+                    if (f[i].current === true) {
+                        format = f[i].name;
+                        break;
+                    }
+                }
+                return format;
+            },
+            getConstraints: function () {
+                return this.constraints;
+            },
+            getOriginators: function () {
+                return this.originators;
+            },
+            getDimensions: function () {
+                return this.dimensions;
+            },
+            getAggregatedLayers: function () {
+                if (this.isAggregate) {
+                    return this.aggregatedLayers;
+                } else {
+                    return;
+                }
+            }
+        };
+        return Layer;
+    }();
+    ServicesAutoConfResponseModelLegend = function () {
+        function Legend() {
+            if (!(this instanceof Legend)) {
+                throw new TypeError('Legend constructor cannot be called as a function.');
+            }
+            this.format = null;
+            this.url = null;
+            this.minScaleDenominator = null;
+        }
+        Legend.prototype = { constructor: Legend };
+        return Legend;
+    }();
+    ServicesAutoConfResponseModelMetadata = function () {
+        function Metadata() {
+            if (!(this instanceof Metadata)) {
+                throw new TypeError('Metadata constructor cannot be called as a function.');
+            }
+            this.format = null;
+            this.url = null;
+        }
+        Metadata.prototype = { constructor: Metadata };
+        return Metadata;
+    }();
+    ServicesAutoConfResponseModelOriginator = function () {
+        function Originator() {
+            if (!(this instanceof Originator)) {
+                throw new TypeError('Originator constructor cannot be called as a function.');
+            }
+            this.name = null;
+            this.attribution = null;
+            this.logo = null;
+            this.url = null;
+            this.constraints = [];
+        }
+        Originator.prototype = { constructor: Originator };
+        return Originator;
+    }();
+    ServicesAutoConfResponseModelService = function () {
+        function Service() {
+            if (!(this instanceof Service)) {
+                throw new TypeError('Service constructor cannot be called as a function.');
+            }
+            this.title = null;
+            this.serverUrl = null;
+            this.version = null;
+        }
+        Service.prototype = { constructor: Service };
+        return Service;
+    }();
+    ServicesAutoConfResponseModelStyle = function () {
+        function Style() {
+            if (!(this instanceof Style)) {
+                throw new TypeError('Style constructor cannot be called as a function.');
+            }
+            this.name = null;
+            this.title = null;
+            this.current = null;
+        }
+        Style.prototype = { constructor: Style };
+        return Style;
+    }();
+    ServicesAutoConfResponseModelTerritory = function () {
+        function Territory() {
+            if (!(this instanceof Territory)) {
+                throw new TypeError('Territory constructor cannot be called as a function.');
+            }
+            this.isDefault = null;
+            this.defaultCRS = null;
+            this.additionalCRS = [];
+            this.geoBBOX = {
+                left: null,
+                right: null,
+                top: null,
+                bottom: null
+            };
+            this.geoCenter = {
+                lon: null,
+                lat: null
+            };
+            this.defaultOptions = {
+                resolution: null,
+                minScaleDenominator: null,
+                maxScaleDenominator: null
+            };
+            this.defaultLayers = [];
+        }
+        Territory.prototype = { constructor: Territory };
+        return Territory;
+    }();
+    ServicesAutoConfResponseModelThematic = function () {
+        function Thematic() {
+            if (!(this instanceof Thematic)) {
+                throw new TypeError('Thematic constructor cannot be called as a function.');
+            }
+            this.inspire = null;
+            this.name = null;
+        }
+        Thematic.prototype = { constructor: Thematic };
+        return Thematic;
+    }();
+    ServicesAutoConfResponseModelTileMatrixSet = function () {
+        function TileMatrixSet() {
+            if (!(this instanceof TileMatrixSet)) {
+                throw new TypeError('TileMatrixSet constructor cannot be called as a function.');
+            }
+            this.projection = null;
+            this.nativeResolutions = [];
+            this.matrixIds = [];
+            this.tileMatrices = {};
+        }
+        TileMatrixSet.prototype = {
+            constructor: TileMatrixSet,
+            getResolutions: function () {
+                return this.nativeResolutions;
+            },
+            getMatrixIds: function () {
+                return this.matrixIds;
+            },
+            getProjection: function () {
+                return this.projection;
+            },
+            getTileMatrices: function () {
+                return this.tileMatrices;
+            },
+            getTopLeftCorner: function () {
+                var topLeftCorner;
+                var matrices = this.getTileMatrices();
+                if (matrices) {
+                    for (var id in matrices) {
+                        if (matrices.hasOwnProperty(id)) {
+                            topLeftCorner = matrices[id].topLeftCorner;
+                            break;
+                        }
+                    }
+                }
+                return topLeftCorner;
+            }
+        };
+        return TileMatrixSet;
+    }();
+    ServicesAutoConfResponseModelTileMatrix = function () {
+        function TileMatrix() {
+            if (!(this instanceof TileMatrix)) {
+                throw new TypeError('TileMatrix constructor cannot be called as a function.');
+            }
+            this.matrixId = null;
+            this.matrixHeight = null;
+            this.matrixWidth = null;
+            this.scaleDenominator = null;
+            this.tileHeight = null;
+            this.tileWidth = null;
+            this.topLeftCorner = null;
+        }
+        TileMatrix.prototype = {
+            constructor: TileMatrix,
+            getTopLeftCorner: function () {
+                return this.topLeftCorner;
+            },
+            getScaleDenominator: function () {
+                return this.scaleDenominator;
+            },
+            getTileHeight: function () {
+                return this.tileHeight;
+            },
+            getTileWidth: function () {
+                return this.tileWidth;
+            },
+            getMatrixHeight: function () {
+                return this.matrixHeight;
+            },
+            getMatrixWidth: function () {
+                return this.matrixWidth;
+            }
+        };
+        return TileMatrix;
+    }();
+    ServicesAutoConfResponseModelTileMatrixLimit = function () {
+        function TileMatrixLimit() {
+            if (!(this instanceof TileMatrixLimit)) {
+                throw new TypeError('TileMatrixLimit constructor cannot be called as a function.');
+            }
+            this.minTileRow = null;
+            this.maxTileRow = null;
+            this.minTileCol = null;
+            this.maxTileCol = null;
+        }
+        TileMatrixLimit.prototype = { constructor: TileMatrixLimit };
+        return TileMatrixLimit;
+    }();
+    ServicesAutoConfFormatsAutoConfResponseReader = function (Logger, AutoConfResponse, Constraint, Format, Layer, Legend, Metadata, Originator, Service, Style, Territory, Thematic, TileMatrixSet, TileMatrix, TileMatrixLimit) {
+        var AutoConfResponseReader = {};
+        AutoConfResponseReader.VERSION = '1.1.0';
+        AutoConfResponseReader.NAMESPACES = {
+            xmlns: 'http://www.opengis.net/context',
+            gpp: 'http://api.ign.fr/geoportail',
+            ows: 'http://www.opengis.net/ows/1.1',
+            sld: 'http://www.opengis.net/sld',
+            wmts: 'http://www.opengis.net/wmts/1.0',
+            xlink: 'http://www.w3.org/1999/xlink',
+            xsi: 'http://www.w3.org/2001/XMLSchema-instance'
+        };
+        AutoConfResponseReader.SCHEMALOCATION = [
+            'http://www.opengis.net/context http://gpp3-wxs.ign.fr/schemas/extContext.xsd http://api.ign.fr/geoportail http://wxs.ign.fr/schemas/autoconf/autoconf.xsd',
+            'http://www.opengis.net/context http://gpp3-wxs.ign.fr/schemas/extContext.xsd http://api.ign.fr/geoportail http://gpp3-wxs.ign.fr/schemas/autoconf.xsd'
+        ];
+        AutoConfResponseReader.DEFAULTPREFIX = 'context';
+        AutoConfResponseReader.READERS = {
+            context: {
+                ViewContext: function (viewContextNode) {
+                    __checkServiceAttributes(viewContextNode);
+                    var config = new AutoConfResponse();
+                    __getChildNodes(viewContextNode, config);
+                    return config;
+                },
+                Title: function (titleNode, data) {
+                    if (data && data.generalOptions) {
+                        data.generalOptions.title = __getChildValue(titleNode);
+                    } else if (data && data.lyr) {
+                        data.lyr.title = __getChildValue(titleNode);
+                    }
+                },
+                Abstract: function (node, data) {
+                    if (data && data.lyr) {
+                        data.lyr.description = __getChildValue(node);
+                    }
+                },
+                Server: function (node, data) {
+                    var serverId = node.getAttribute('service');
+                    var title = node.getAttribute('title');
+                    var version = node.getAttribute('version');
+                    if (serverId) {
+                        if (data && data.services && typeof data.services === 'object' && !data.services[serverId]) {
+                            var s = new Service();
+                            s.title = title;
+                            s.version = version;
+                            __getChildNodes(node, s);
+                            data.services[serverId] = s;
+                        } else if (data && data.lyr) {
+                            if (!data.lyr.serviceParams) {
+                                data.lyr.serviceParams = {};
+                            }
+                            data.lyr.serviceParams.id = serverId;
+                            data.lyr.serviceParams.version = version;
+                        }
+                    }
+                },
+                OnlineResource: function (node, service) {
+                    if (service && service.hasOwnProperty('serverUrl')) {
+                        service.serverUrl = node.getAttribute('xlink:href');
+                    }
+                },
+                LayerList: function (layerListNode, config) {
+                    __getChildNodes(layerListNode, config);
+                    if (config && config.layers && config.generalOptions && config.services) {
+                        for (var lyr in config.layers) {
+                            if (config.layers.hasOwnProperty(lyr)) {
+                                var layerConfig = config.layers[lyr];
+                                var apiKeys = layerConfig.apiKeys;
+                                if (apiKeys && Array.isArray(apiKeys)) {
+                                    for (var i = 0; i < apiKeys.length; i++) {
+                                        var key = apiKeys[i];
+                                        if (config.generalOptions.apiKeys) {
+                                            if (!config.generalOptions.apiKeys[key] || !Array.isArray(config.generalOptions.apiKeys[key])) {
+                                                config.generalOptions.apiKeys[key] = [];
+                                            }
+                                            config.generalOptions.apiKeys[key].push(lyr);
+                                        }
+                                    }
+                                }
+                                var serviceParams = layerConfig.serviceParams;
+                                if (serviceParams && serviceParams.id) {
+                                    if (!config.services[serviceParams.id]) {
+                                        var s = new Service();
+                                        if (serviceParams.serverUrl) {
+                                            s.serverUrl = serviceParams.serverUrl;
+                                        }
+                                        if (serviceParams.version) {
+                                            s.version = serviceParams.version;
+                                        }
+                                        config.services[serviceParams.id] = s;
+                                    }
+                                }
+                                if (layerConfig.wmtsOptions && layerConfig.wmtsOptions.tileMatrixSetLink && config.tileMatrixSets) {
+                                    var tmsLink = layerConfig.wmtsOptions.tileMatrixSetLink;
+                                    var tileMatrixSets = config.tileMatrixSets;
+                                    for (var tms in tileMatrixSets) {
+                                        if (tileMatrixSets.hasOwnProperty(tms) && tms === tmsLink) {
+                                            layerConfig.defaultProjection = tileMatrixSets[tms].projection;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                },
+                Layer: function (layerNode, config) {
+                    if (config && config.layers) {
+                        var lyrData = {
+                            lyr: new Layer(),
+                            lyrId: null
+                        };
+                        var hidden = layerNode.getAttribute('hidden');
+                        if (hidden === '1') {
+                            lyrData.lyr.hidden = true;
+                        } else {
+                            lyrData.lyr.hidden = false;
+                        }
+                        var queryable = layerNode.getAttribute('queryable');
+                        if (queryable === '1') {
+                            lyrData.lyr.queryable = true;
+                        } else {
+                            lyrData.lyr.queryable = false;
+                        }
+                        __getChildNodes(layerNode, lyrData);
+                        if (lyrData.lyrId) {
+                            if (lyrData.lyr.serviceParams && lyrData.lyr.serviceParams.id) {
+                                var serviceid = lyrData.lyr.serviceParams.id;
+                                if (serviceid.toUpperCase().indexOf('OPENLS') !== -1 || serviceid.toUpperCase().indexOf('ELEVATION') !== -1) {
+                                    var resourceId = lyrData.lyrId.split('$')[0];
+                                    lyrData.lyrId = resourceId + '$' + serviceid;
+                                }
+                            }
+                            lyrData.lyr.layerId = lyrData.lyrId;
+                            config.layers[lyrData.lyrId] = lyrData.lyr;
+                        }
+                    }
+                },
+                Name: function (node, lyrData) {
+                    if (lyrData && lyrData.lyr) {
+                        lyrData.lyr.name = __getChildValue(node);
+                    }
+                },
+                SRS: function (node, lyrData) {
+                    if (lyrData && lyrData.lyr) {
+                        lyrData.lyr.defaultProjection = __getChildValue(node);
+                    }
+                },
+                Format: function (node, lyrData) {
+                    if (lyrData && lyrData.lyr) {
+                        var f = new Format();
+                        var current = node.getAttribute('current');
+                        if (current === '1') {
+                            f.current = true;
+                        } else {
+                            f.current = false;
+                        }
+                        f.name = __getChildValue(node);
+                        if (!lyrData.lyr.formats || !Array.isArray(lyrData.lyr.formats)) {
+                            lyrData.lyr.formats = [];
+                        }
+                        lyrData.lyr.formats.push(f);
+                    }
+                },
+                Style: function (node, lyrData) {
+                    if (lyrData && lyrData.lyr) {
+                        var s = new Style();
+                        var current = node.getAttribute('current');
+                        if (current === '1' || current === 1) {
+                            s.current = true;
+                        } else {
+                            s.current = false;
+                        }
+                        if (node.hasChildNodes) {
+                            var children = node.childNodes;
+                            var child;
+                            var childName;
+                            for (var i = 0; i < children.length; i++) {
+                                child = children[i];
+                                if (child.nodeType === 1) {
+                                    childName = child.localName || child.baseName || child.nodeName;
+                                    if (childName === 'Name') {
+                                        s.name = __getChildValue(child);
+                                    } else if (childName === 'Title') {
+                                        s.title = __getChildValue(child);
+                                    }
+                                }
+                            }
+                        }
+                        if (!lyrData.lyr.styles || !Array.isArray(lyrData.lyr.styles)) {
+                            lyrData.lyr.styles = [];
+                        }
+                        lyrData.lyr.styles.push(s);
+                    }
+                },
+                Dimension: function (node, lyrData) {
+                    var name = node.getAttribute('name');
+                    var dim = __getChildValue(node);
+                    if (lyrData && lyrData.lyr) {
+                        if (!lyrData.lyr.dimensions) {
+                            lyrData.lyr.dimensions = {};
+                        }
+                        if (name === 'Type') {
+                            lyrData.lyr.dimensions.type = dim;
+                        } else if (name === 'VisibilityRange') {
+                            lyrData.lyr.dimensions.visibilityRange = dim;
+                        } else if (name === 'VisibilityMode ') {
+                            lyrData.lyr.dimensions.visibilityMode = dim;
+                        } else if (name === 'GeometricType') {
+                            lyrData.lyr.dimensions.geometricType = dim;
+                        } else if (name === 'NoDataValue') {
+                            lyrData.lyr.dimensions.noDataValue = dim;
+                        }
+                    }
+                }
+            },
+            gpp: {
+                Theme: function (themeNode, config) {
+                    if (config && config.generalOptions && config.generalOptions.hasOwnProperty('theme')) {
+                        config.generalOptions.theme = __getChildValue(themeNode);
+                    }
+                },
+                defaultGMLGFIStyleUrl: function (node, config) {
+                    if (config && config.generalOptions && config.generalOptions.hasOwnProperty('defaultGMLGFIStyle')) {
+                        config.generalOptions.defaultGMLGFIStyle = __getChildValue(node);
+                    }
+                },
+                Territory: function (territoryNode, config) {
+                    var tid = territoryNode.getAttribute('id');
+                    if (tid) {
+                        var t = new Territory();
+                        var isDefault = territoryNode.getAttribute('default');
+                        if (isDefault === '1') {
+                            t.isDefault = true;
+                        } else {
+                            t.isDefault = false;
+                        }
+                        __getChildNodes(territoryNode, t);
+                        if (config && config.territories && typeof config.territories === 'object') {
+                            config.territories[tid] = t;
+                        }
+                    }
+                },
+                defaultCRS: function (node, territory) {
+                    if (territory && territory.hasOwnProperty('defaultCRS')) {
+                        territory.defaultCRS = __getChildValue(node);
+                    }
+                },
+                AdditionalCRS: function (node, data) {
+                    var addCRS = __getChildValue(node);
+                    if (addCRS && data) {
+                        if (Array.isArray(data.additionalCRS)) {
+                            data.additionalCRS.push(addCRS);
+                        } else {
+                            if (!data.additionalProjections || !Array.isArray(data.additionalProjections)) {
+                                data.additionalProjections = [];
+                            }
+                            data.additionalProjections.push(addCRS);
+                        }
+                    }
+                },
+                DefaultLayer: function (node, territory) {
+                    var lyr = node.getAttribute('layerId');
+                    if (lyr && territory && Array.isArray(territory.defaultLayers)) {
+                        territory.defaultLayers.push(lyr);
+                    }
+                },
+                BoundingBox: function (node, data) {
+                    if (data) {
+                        var values = __getChildValue(node).split(',');
+                        if (values.length === 4) {
+                            var bbox = {
+                                left: parseFloat(values[0]),
+                                right: parseFloat(values[2]),
+                                top: parseFloat(values[3]),
+                                bottom: parseFloat(values[1])
+                            };
+                            var minT = node.getAttribute('minT');
+                            var maxT = node.getAttribute('maxT');
+                            if (data.hasOwnProperty('geoBBOX')) {
+                                data.geoBBOX = bbox;
+                            } else if (data.hasOwnProperty('bbox')) {
+                                if (data.bbox.left || data.bbox.right || data.bbox.top || data.bbox.bottom) {
+                                    if (!data.multiConstraints) {
+                                        data.multiConstraints = [];
+                                    }
+                                    var newConstraint = new Constraint();
+                                    newConstraint.bbox = bbox;
+                                    newConstraint.temporalExtent = [
+                                        minT,
+                                        maxT
+                                    ];
+                                    data.multiConstraints.push(newConstraint);
+                                } else {
+                                    data.bbox = bbox;
+                                    data.temporalExtent = [
+                                        minT,
+                                        maxT
+                                    ];
+                                }
+                            } else {
+                                if (!data.globalConstraint) {
+                                    data.globalConstraint = new Constraint();
+                                }
+                                data.globalConstraint.bbox = bbox;
+                                data.globalConstraint.temporalExtent = [
+                                    minT,
+                                    maxT
+                                ];
+                            }
+                        }
+                    }
+                },
+                Resolution: function (node, territory) {
+                    var res = __getChildValue(node);
+                    if (res && territory && territory.defaultOptions && territory.defaultOptions.hasOwnProperty('resolution')) {
+                        territory.defaultOptions.resolution = parseFloat(res);
+                    }
+                },
+                x: function (node, territory) {
+                    var lon = __getChildValue(node);
+                    if (lon && territory && territory.geoCenter && territory.geoCenter.hasOwnProperty('lon')) {
+                        territory.geoCenter.lon = parseFloat(lon);
+                    }
+                },
+                y: function (node, territory) {
+                    var lat = __getChildValue(node);
+                    if (lat && territory && territory.geoCenter && territory.geoCenter.hasOwnProperty('lat')) {
+                        territory.geoCenter.lat = parseFloat(lat);
+                    }
+                },
+                Resolutions: function (resNode, config) {
+                    if (config && config.generalOptions && config.generalOptions.hasOwnProperty('wgs84Resolutions')) {
+                        config.generalOptions.wgs84Resolutions = __getChildValue(resNode).split(',');
+                    }
+                },
+                Layer: function (node, lyrData) {
+                    if (lyrData && lyrData.hasOwnProperty('lyrId') && lyrData.lyr) {
+                        lyrData.lyrId = node.getAttribute('id');
+                        var aggregate = node.getAttribute('aggregate');
+                        var more = node.getAttribute('more');
+                        if (aggregate || more) {
+                            lyrData.lyr.isAggregate = true;
+                        }
+                        __getChildNodes(node, lyrData.lyr);
+                    }
+                },
+                Constraint: function (node, data) {
+                    var c = new Constraint();
+                    __getChildNodes(node, c);
+                    if (data) {
+                        if (!data.constraints || !Array.isArray(data.constraints)) {
+                            data.constraints = [];
+                        }
+                        if (c.multiConstraints && Array.isArray(c.multiConstraints)) {
+                            var constraint = new Constraint();
+                            constraint.crs = c.crs;
+                            constraint.bbox = c.bbox;
+                            constraint.minScaleDenominator = c.minScaleDenominator;
+                            constraint.maxScaleDenominator = c.maxScaleDenominator;
+                            constraint.temporalExtent = c.temporalExtent;
+                            data.constraints.push(constraint);
+                            for (var i = 0; i < c.multiConstraints.length; i++) {
+                                constraint = new Constraint();
+                                constraint.crs = c.crs;
+                                constraint.minScaleDenominator = c.minScaleDenominator;
+                                constraint.maxScaleDenominator = c.maxScaleDenominator;
+                                constraint.bbox = c.multiConstraints[i].bbox;
+                                constraint.temporalExtent = c.multiConstraints[i].temporalExtent;
+                                data.constraints.push(constraint);
+                            }
+                        } else {
+                            data.constraints.push(c);
+                        }
+                    }
+                },
+                CRS: function (node, data) {
+                    if (data && data.hasOwnProperty('crs')) {
+                        data.crs = __getChildValue(node);
+                    }
+                },
+                Thematic: function (node, lyr) {
+                    if (lyr) {
+                        var t = new Thematic();
+                        t.inspire = false;
+                        t.name = __getChildValue(node);
+                        if (!lyr.thematics || !Array.isArray(lyr.thematics)) {
+                            lyr.thematics = [];
+                        }
+                        lyr.thematics.push(t);
+                    }
+                },
+                InspireThematic: function (node, lyr) {
+                    if (lyr) {
+                        var t = new Thematic();
+                        t.inspire = true;
+                        t.name = __getChildValue(node);
+                        if (!lyr.thematics || !Array.isArray(lyr.thematics)) {
+                            lyr.thematics = [];
+                        }
+                        lyr.thematics.push(t);
+                    }
+                },
+                Originator: function (node, lyr) {
+                    if (lyr) {
+                        var o = new Originator();
+                        o.name = node.getAttribute('name');
+                        __getChildNodes(node, o);
+                        if (!lyr.originators || !Array.isArray(lyr.originators)) {
+                            lyr.originators = [];
+                        }
+                        lyr.originators.push(o);
+                    }
+                },
+                Attribution: function (node, originator) {
+                    if (originator && originator.hasOwnProperty('attribution')) {
+                        originator.attribution = __getChildValue(node);
+                    }
+                },
+                Logo: function (node, originator) {
+                    if (originator && originator.hasOwnProperty('logo')) {
+                        originator.logo = __getChildValue(node);
+                    }
+                },
+                URL: function (node, originator) {
+                    if (originator && originator.hasOwnProperty('url')) {
+                        originator.url = __getChildValue(node);
+                    }
+                },
+                Legend: function (node, lyr) {
+                    var l = new Legend();
+                    __getChildNodes(node, l);
+                    if (lyr) {
+                        if (!lyr.legends || !Array.isArray(lyr.legends)) {
+                            lyr.legends = [];
+                        }
+                        lyr.legends.push(l);
+                    }
+                },
+                LegendURL: function (node, legend) {
+                    if (legend && legend.hasOwnProperty('format')) {
+                        legend.format = node.getAttribute('format');
+                        if (node.hasChildNodes) {
+                            var child = node.childNodes[0];
+                            var childName = child.localName || child.baseName || child.nodeName;
+                            if (childName === 'OnlineResource' && legend.hasOwnProperty('url')) {
+                                legend.url = child.getAttribute('xlink:href');
+                            }
+                        }
+                    }
+                },
+                QuickLook: function (node, lyr) {
+                    if (node.hasChildNodes) {
+                        var child = node.childNodes[0];
+                        var childName = child.localName || child.baseName || child.nodeName;
+                        if (childName === 'OnlineResource' && lyr) {
+                            lyr.quicklookUrl = child.getAttribute('xlink:href');
+                        }
+                    }
+                },
+                MetadataURL: function (node, lyr) {
+                    if (lyr) {
+                        var m = new Metadata();
+                        m.format = node.getAttribute('format');
+                        if (node.hasChildNodes) {
+                            var child = node.childNodes[0];
+                            var childName = child.localName || child.baseName || child.nodeName;
+                            if (childName === 'OnlineResource') {
+                                m.url = child.getAttribute('xlink:href');
+                            }
+                        }
+                        if (!lyr.metadata && !Array.isArray(lyr.metadata)) {
+                            lyr.metadata = [];
+                        }
+                        lyr.metadata.push(m);
+                    }
+                },
+                Key: function (node, lyr) {
+                    if (lyr) {
+                        var key = node.getAttribute('id');
+                        if (!lyr.apiKeys || !Array.isArray(lyr.apiKeys)) {
+                            lyr.apiKeys = [];
+                        }
+                        lyr.apiKeys.push(key);
+                        var serverUrl = __getChildValue(node);
+                        if (!lyr.serviceParams) {
+                            lyr.serviceParams = {};
+                        }
+                        if (!lyr.serviceParams.serverUrl) {
+                            lyr.serviceParams.serverUrl = {};
+                        }
+                        if (!lyr.serviceParams.serverUrl[key]) {
+                            lyr.serviceParams.serverUrl[key] = serverUrl;
+                        }
+                    }
+                }
+            },
+            ows: {
+                Identifier: function (node, data) {
+                    if (data && data.hasOwnProperty('TMS')) {
+                        data.identifier = __getChildValue(node);
+                    } else if (data && data.hasOwnProperty('matrixId')) {
+                        data.matrixId = __getChildValue(node);
+                    }
+                },
+                SupportedCRS: function (node, tmsData) {
+                    if (tmsData && tmsData.TMS && tmsData.TMS.hasOwnProperty('projection')) {
+                        tmsData.TMS.projection = __getChildValue(node);
+                    }
+                }
+            },
+            sld: {
+                MinScaleDenominator: function (node, data) {
+                    var minScale = __getChildValue(node);
+                    if (minScale && data) {
+                        if (data.hasOwnProperty('defaultOptions')) {
+                            data.defaultOptions.minScaleDenominator = parseFloat(minScale);
+                        } else if (data.lyr) {
+                            if (!data.lyr.globalConstraint) {
+                                data.lyr.globalConstraint = new Constraint();
+                            }
+                            data.lyr.globalConstraint.minScaleDenominator = parseFloat(minScale);
+                        } else if (data.hasOwnProperty('minScaleDenominator')) {
+                            data.minScaleDenominator = parseFloat(minScale);
+                        }
+                    }
+                },
+                MaxScaleDenominator: function (node, data) {
+                    var maxScale = __getChildValue(node);
+                    if (maxScale && data) {
+                        if (data.hasOwnProperty('defaultOptions')) {
+                            data.defaultOptions.maxScaleDenominator = parseFloat(maxScale);
+                        } else if (data.lyr) {
+                            if (!data.lyr.globalConstraint) {
+                                data.lyr.globalConstraint = new Constraint();
+                            }
+                            data.lyr.globalConstraint.maxScaleDenominator = parseFloat(maxScale);
+                        } else if (data.hasOwnProperty('maxScaleDenominator')) {
+                            data.maxScaleDenominator = parseFloat(maxScale);
+                        }
+                    }
+                }
+            },
+            wmts: {
+                TileMatrixSetLimits: function (node, lyr) {
+                    if (lyr) {
+                        var limits = {};
+                        __getChildNodes(node, limits);
+                        if (!lyr.wmtsOptions) {
+                            lyr.wmtsOptions = {};
+                        }
+                        lyr.wmtsOptions.tileMatrixSetLimits = limits;
+                    }
+                },
+                TileMatrixLimits: function (node, limits) {
+                    var limit = new TileMatrixLimit();
+                    var limitId;
+                    if (node.hasChildNodes) {
+                        var children = node.childNodes;
+                        for (var i = 0; i < children.length; i++) {
+                            var child = children[i];
+                            var childName = child.localName || child.baseName || child.nodeName;
+                            if (childName === 'TileMatrix') {
+                                limitId = __getChildValue(child);
+                            } else if (childName === 'MinTileRow') {
+                                limit.minTileRow = __getChildValue(child);
+                            } else if (childName === 'MaxTileRow') {
+                                limit.maxTileRow = __getChildValue(child);
+                            } else if (childName === 'MinTileCol') {
+                                limit.minTileCol = __getChildValue(child);
+                            } else if (childName === 'MaxTileCol') {
+                                limit.maxTileCol = __getChildValue(child);
+                            }
+                        }
+                        if (limitId && limits && !limits[limitId]) {
+                            limits[limitId] = limit;
+                        }
+                    }
+                },
+                TileMatrixSet: function (node, data) {
+                    if (data && data.tileMatrixSets) {
+                        var tmsData = {};
+                        tmsData.TMS = new TileMatrixSet();
+                        tmsData.resolutions = [];
+                        __getChildNodes(node, tmsData);
+                        var tileMatrices = tmsData.TMS.tileMatrices;
+                        for (var tm in tileMatrices) {
+                            if (tileMatrices.hasOwnProperty(tm)) {
+                                tmsData.TMS.matrixIds.push(tm);
+                            }
+                        }
+                        if (tmsData.TMS.getProjection() === 'IGNF:WGS84G' || tmsData.TMS.getProjection() === 'EPSG:4326') {
+                            if (data.generalOptions && Array.isArray(data.generalOptions.wgs84Resolutions)) {
+                                var wgs84Resolutions = data.generalOptions.wgs84Resolutions;
+                                for (var i = 0; i < wgs84Resolutions.length; i++) {
+                                    tmsData.resolutions[i] = parseFloat(wgs84Resolutions[i]);
+                                }
+                            }
+                        }
+                        if (Array.isArray(tmsData.resolutions) && tmsData.resolutions.sort !== undefined) {
+                            tmsData.resolutions.sort(function (x, y) {
+                                return y - x;
+                            });
+                        }
+                        tmsData.TMS.nativeResolutions = tmsData.resolutions;
+                        data.tileMatrixSets[tmsData.identifier] = tmsData.TMS;
+                    } else {
+                        if (data && !data.wmtsOptions) {
+                            data.wmtsOptions = {};
+                        }
+                        data.wmtsOptions.tileMatrixSetLink = __getChildValue(node);
+                    }
+                },
+                TileMatrix: function (node, tmsData) {
+                    if (tmsData) {
+                        var tileMatrix = new TileMatrix();
+                        __getChildNodes(node, tileMatrix);
+                        if (tmsData.TMS && tmsData.TMS.getProjection()) {
+                            var proj = tmsData.TMS.getProjection();
+                            if (proj === 'EPSG:3857' || proj === 'EPSG:2154') {
+                                var r = tileMatrix.scaleDenominator * 0.00028;
+                                if (tmsData.resolutions && Array.isArray(tmsData.resolutions)) {
+                                    tmsData.resolutions.push(r);
+                                }
+                            }
+                        }
+                        if (tmsData.TMS && tmsData.TMS.tileMatrices) {
+                            tmsData.TMS.tileMatrices[tileMatrix.matrixId] = tileMatrix;
+                        }
+                    }
+                },
+                ScaleDenominator: function (node, tileMatrix) {
+                    var scale = __getChildValue(node);
+                    if (scale && tileMatrix && tileMatrix.hasOwnProperty('scaleDenominator')) {
+                        tileMatrix.scaleDenominator = parseFloat(scale);
+                    }
+                },
+                TopLeftCorner: function (node, tileMatrix) {
+                    var values = __getChildValue(node).split(' ');
+                    if (values && tileMatrix) {
+                        tileMatrix.topLeftCorner = {};
+                        tileMatrix.topLeftCorner.x = parseFloat(values[0]);
+                        tileMatrix.topLeftCorner.y = parseFloat(values[1]);
+                    }
+                },
+                TileWidth: function (node, tileMatrix) {
+                    var value = __getChildValue(node);
+                    if (value && tileMatrix && tileMatrix.hasOwnProperty('tileWidth')) {
+                        tileMatrix.tileWidth = parseInt(value, 10);
+                    }
+                },
+                TileHeight: function (node, tileMatrix) {
+                    var value = __getChildValue(node);
+                    if (value && tileMatrix && tileMatrix.hasOwnProperty('tileHeight')) {
+                        tileMatrix.tileHeight = parseInt(value, 10);
+                    }
+                },
+                MatrixWidth: function (node, tileMatrix) {
+                    var value = __getChildValue(node);
+                    if (value && tileMatrix && tileMatrix.hasOwnProperty('matrixWidth')) {
+                        tileMatrix.matrixWidth = parseInt(value, 10);
+                    }
+                },
+                MatrixHeight: function (node, tileMatrix) {
+                    var value = __getChildValue(node);
+                    if (value && tileMatrix && tileMatrix.hasOwnProperty('matrixHeight')) {
+                        tileMatrix.matrixHeight = parseInt(value, 10);
+                    }
+                }
+            },
+            serviceException: function (node) {
+                var response = {};
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (child.nodeName === 'exception') {
+                            response.exceptionReport = AutoConfResponseReader.READERS['exception'](child);
+                        }
+                    }
+                }
+                return response;
+            },
+            exception: function (node) {
+                var exceptionReport = {};
+                var exceptionCode = node.getAttribute('code');
+                if (exceptionCode) {
+                    exceptionReport.exceptionCode = exceptionCode;
+                }
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    exceptionReport.exception = textNode.nodeValue;
+                }
+                return exceptionReport;
+            }
+        };
+        AutoConfResponseReader.read = function (root) {
+            if (root.nodeName === 'ViewContext') {
+                var nsPrefix = root.prefix || AutoConfResponseReader.DEFAULTPREFIX;
+                var config = AutoConfResponseReader.READERS[nsPrefix][root.nodeName](root);
+                return config;
+            } else if (root.nodeName === 'serviceException') {
+                var exceptionReport = AutoConfResponseReader.READERS[root.nodeName](root);
+                return exceptionReport;
+            } else {
+                throw new Error('Erreur lors de la lecture de la réponse : elle n\'est pas au format attendu.');
+            }
+        };
+        function __getAttributes(node) {
+            if (node.attributes.length > 0) {
+                var nodeAttributes = {};
+                var attributes = node.attributes;
+                for (var i = 0; i < attributes.length; i++) {
+                    var attribute = attributes[i];
+                    nodeAttributes[attribute.nodeName] = attribute.nodeValue;
+                }
+                return nodeAttributes;
+            }
+        }
+        function __getChildNodes(node, data) {
+            if (node.hasChildNodes()) {
+                var children = node.childNodes;
+                var child;
+                var childName;
+                var childPrefix;
+                for (var i = 0; i < children.length; i++) {
+                    child = children[i];
+                    if (child.nodeType === 1) {
+                        childName = child.localName || child.baseName || child.nodeName;
+                        childPrefix = child.prefix || AutoConfResponseReader.DEFAULTPREFIX;
+                        if (AutoConfResponseReader.READERS[childPrefix][childName]) {
+                            var reader = AutoConfResponseReader.READERS[childPrefix][childName];
+                            reader(child, data);
+                        } else {
+                            __getChildNodes(child, data);
+                        }
+                    }
+                }
+            }
+        }
+        function __getChildValue(node) {
+            var textNode;
+            var value = '';
+            if (node.hasChildNodes()) {
+                textNode = node.firstChild;
+                if (textNode.nodeType === 3 || textNode.nodeType === 4) {
+                    value = textNode.nodeValue;
+                }
+            }
+            return value;
+        }
+        function __checkServiceAttributes(viewContextNode) {
+            if (viewContextNode.attributes.length > 0) {
+                var xlsAttributes = __getAttributes(viewContextNode);
+                for (var att in xlsAttributes) {
+                    if (xlsAttributes.hasOwnProperty(att)) {
+                        if (att === 'version') {
+                            if (xlsAttributes['version'] !== AutoConfResponseReader.VERSION) {
+                                console.log('[AutoConfResponseReader] autoconf version is not the expected one : there may be errors in parsing');
+                                return;
+                            }
+                        }
+                        if (att === 'xmlns') {
+                            if (xlsAttributes[att] !== AutoConfResponseReader.NAMESPACES.xmlns) {
+                                console.log('[AutoConfResponseReader] autoconf response default namespace is not the expected one');
+                                return;
+                            }
+                            continue;
+                        }
+                        var prefix = att.split(':')[0];
+                        var ns = att.split(':')[1];
+                        if (prefix === 'xmlns' && ns) {
+                            if (AutoConfResponseReader.NAMESPACES[ns]) {
+                                if (AutoConfResponseReader.NAMESPACES[ns] !== xlsAttributes[att]) {
+                                    console.log('[AutoConfResponseReader] autoconf response ' + att + ' namespace is not the expected one');
+                                    return;
+                                }
+                            }
+                        }
+                        if (ns === 'schemaLocation') {
+                            if (xlsAttributes[att] !== AutoConfResponseReader.SCHEMALOCATION[0] && xlsAttributes[att] !== AutoConfResponseReader.SCHEMALOCATION[1]) {
+                                console.log('[AutoConfResponseReader] autoconf response schema location is not the expected one');
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return AutoConfResponseReader;
+    }(UtilsLoggerByDefault, ServicesAutoConfResponseModelAutoConfResponse, ServicesAutoConfResponseModelConstraint, ServicesAutoConfResponseModelFormat, ServicesAutoConfResponseModelLayer, ServicesAutoConfResponseModelLegend, ServicesAutoConfResponseModelMetadata, ServicesAutoConfResponseModelOriginator, ServicesAutoConfResponseModelService, ServicesAutoConfResponseModelStyle, ServicesAutoConfResponseModelTerritory, ServicesAutoConfResponseModelThematic, ServicesAutoConfResponseModelTileMatrixSet, ServicesAutoConfResponseModelTileMatrix, ServicesAutoConfResponseModelTileMatrixLimit);
+    ServicesAutoConfResponseAutoConfResponseFactory = function (Logger, ErrorService, MRes, XML, AutoConfResponseReader) {
+        var AutoConfReponseFactory = {
+            build: function (options) {
+                var data = null;
+                if (options.response) {
+                    if (options.rawResponse) {
+                        data = options.response;
+                    } else {
+                        try {
+                            var p = new XML({ reader: AutoConfResponseReader });
+                            if (typeof options.response === 'string') {
+                                p.setXMLString(options.response);
+                            } else {
+                                p.setXMLDoc(options.response);
+                            }
+                            data = p.parse();
+                        } catch (e) {
+                            var message = e.message;
+                            if (typeof options.response === 'string') {
+                                message += '\n(raw response service\'' + options.response + '\')';
+                            } else {
+                                message += '\n(raw response service\'' + options.response.documentElement.innerHTML + '\')';
+                            }
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', message),
+                                status: 200,
+                                type: ErrorService.TYPE_SRVERR
+                            }));
+                            return;
+                        }
+                        var isEmpty = true;
+                        for (var key in data) {
+                            if (data.hasOwnProperty(key)) {
+                                isEmpty = false;
+                            }
+                        }
+                        if (isEmpty) {
+                            options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EMPTY_2')));
+                            return;
+                        }
+                        if (data.exceptionReport) {
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', data.exceptionReport),
+                                type: ErrorService.TYPE_SRVERR,
+                                status: 200
+                            }));
+                            return;
+                        }
+                    }
+                } else {
+                    options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EMPTY')));
+                    return;
+                }
+                var scope = typeof window !== 'undefined' ? window : {};
+                if (!scope.Gp) {
+                    scope.Gp = {};
+                }
+                if (!scope.Gp.Config) {
+                    scope.Gp.Config = data;
+                } else {
+                    this.mergeConfig(scope.Gp.Config, data, options.layerId);
+                }
+                options.onSuccess.call(options.scope, scope.Gp.Config);
+                return;
+            },
+            mergeConfig: function (GpConfig, data, layerId) {
+                if (data && GpConfig) {
+                    for (var prop in data) {
+                        if (data.hasOwnProperty(prop)) {
+                            if (prop == 'generalOptions') {
+                                for (var key in data[prop].apiKeys) {
+                                    if (data[prop].apiKeys.hasOwnProperty(key) && !GpConfig.generalOptions.apiKeys[key]) {
+                                        GpConfig.generalOptions.apiKeys[key] = data[prop].apiKeys[key];
+                                    }
+                                }
+                            } else {
+                                if (GpConfig[prop]) {
+                                    for (var obj in data[prop]) {
+                                        if (data[prop].hasOwnProperty(obj) && !GpConfig[prop][obj]) {
+                                            GpConfig[prop][obj] = data[prop][obj];
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if (layerId) {
+                        var aggregatedLayers = [];
+                        for (var lyr in data.layers) {
+                            if (data.layers.hasOwnProperty(lyr)) {
+                                aggregatedLayers.push(lyr);
+                            }
+                        }
+                        if (GpConfig.layers[layerId]) {
+                            GpConfig.layers[layerId].aggregatedLayers = aggregatedLayers;
+                        }
+                    }
+                }
+            }
+        };
+        return AutoConfReponseFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, UtilsMessagesResources, FormatsXML, ServicesAutoConfFormatsAutoConfResponseReader);
+    ServicesAutoConfAutoConf = function (Logger, _, ErrorService, Helper, DefaultUrlService, CommonService, AutoConfResponseFactory) {
+        function AutoConf(options) {
+            if (!(this instanceof AutoConf)) {
+                throw new TypeError(_.getMessage('CLASS_CONSTRUCTOR', 'AutoConf'));
+            }
+            this.CLASSNAME = 'AutoConf';
+            CommonService.apply(this, arguments);
+            if (!this.options.serverUrl) {
+                if (!this.options.serverUrl) {
+                    var lstUrlByDefault = DefaultUrlService.AutoConf.url(this.options.apiKey);
+                    if (!this.options.layerId) {
+                        if (Array.isArray(this.options.apiKey) && this.options.apiKey.length > 0) {
+                            this.options.serverUrl = lstUrlByDefault.apiKeys;
+                        } else {
+                            this.options.serverUrl = lstUrlByDefault.apiKey;
+                        }
+                    } else {
+                        this.options.serverUrl = lstUrlByDefault.aggregate + this.options.layerId;
+                    }
+                }
+            }
+            if (this.options.protocol === 'XHR' && this.options.httpMethod === 'POST') {
+                this.options.httpMethod = 'GET';
+            }
+            this.options.outputFormat = 'xml';
+        }
+        AutoConf.prototype = Object.create(CommonService.prototype, {});
+        AutoConf.prototype.constructor = AutoConf;
+        AutoConf.prototype.buildRequest = function (error, success) {
+            var scope = typeof window !== 'undefined' ? window : {};
+            if (scope.Gp && scope.Gp.Config && scope.Gp.Config.generalOptions && scope.Gp.Config.layers) {
+                if (scope.Gp.Config.generalOptions.apiKeys[this.options.apiKey]) {
+                    if (this.options.layerId) {
+                        if (scope.Gp.Config.layers[this.options.layerId] && scope.Gp.Config.layers[this.options.layerId].aggregatedLayers) {
+                            this.options.onSuccess.call(this, scope.Gp.Config);
+                            return;
+                        }
+                    } else {
+                        this.options.onSuccess.call(this, scope.Gp.Config);
+                        return;
+                    }
+                }
+            }
+            this.request = '';
+            var bLocal;
+            if (this.options.serverUrl.indexOf('http://') === -1) {
+                bLocal = true;
+            } else {
+                bLocal = false;
+            }
+            if (!bLocal && this.layerId) {
+                this.request = Helper.normalyzeParameters({ layerId: this.layerId });
+            }
+            success.call(this, this.request);
+        };
+        AutoConf.prototype.analyzeResponse = function (error, success) {
+            if (this.response) {
+                var options = {
+                    layerId: this.options.layerId,
+                    response: this.response,
+                    rawResponse: this.options.rawResponse,
+                    onSuccess: success,
+                    onError: error,
+                    scope: this
+                };
+                AutoConfResponseFactory.build(options);
+            } else {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_RESPONSE_EMPTY')));
+            }
+        };
+        return AutoConf;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, UtilsHelper, ServicesDefaultUrlService, ServicesCommonService, ServicesAutoConfResponseAutoConfResponseFactory);
+    FormatsXLSRequestHeader = function (Logger) {
+        function RequestHeader(options) {
+            if (!(this instanceof RequestHeader)) {
+                throw new TypeError('RequestHeader constructor cannot be called as a function.');
+            }
+            this.options = options || { srsName: 'EPSG:4326' };
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+        }
+        RequestHeader.prototype = {
+            requestString: null,
+            template: '<RequestHeader srsName="__SRSNAME__"/>',
+            constructor: RequestHeader,
+            toString: function () {
+                var template = null;
+                template = this.template;
+                template = template.replace(/__SRSNAME__/g, this.options.srsName);
+                this.requestString = template;
+                return this.requestString;
+            }
+        };
+        return RequestHeader;
+    }(UtilsLoggerByDefault);
+    FormatsXLSRequest = function (Logger) {
+        function Request(options) {
+            if (!(this instanceof Request)) {
+                throw new TypeError('Request constructor cannot be called as a function.');
+            }
+            this.options = options || {
+                maximumResponses: 25,
+                methodName: null,
+                version: '1.2'
+            };
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+        }
+        Request.prototype = {
+            requestString: null,
+            template: '<Request maximumResponses="__MAXRESPONSES__" methodName="__METHODNAME__" requestID="__UUID__" version="__VERSION__">' + '<!-- __REQUESTSERVICE__ -->' + '</Request>',
+            constructor: Request,
+            guid: function () {
+                return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
+                    var r = Math.random() * 16 | 0;
+                    var v = c === 'x' ? r : r & 3 | 8;
+                    return v.toString(16);
+                });
+            },
+            toString: function () {
+                var template = null;
+                template = this.template;
+                template = template.replace(/__MAXRESPONSES__/g, this.options.maximumResponses);
+                template = template.replace(/__METHODNAME__/g, this.options.methodName);
+                template = template.replace(/__UUID__/g, this.guid());
+                template = template.replace(/__VERSION__/g, this.options.version);
+                this.requestString = template;
+                return this.requestString;
+            }
+        };
+        return Request;
+    }(UtilsLoggerByDefault);
+    FormatsXLSAbstractService = function (Logger) {
+        function AbstractService(options) {
+            if (!(this instanceof AbstractService)) {
+                throw new TypeError('AbstractService constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+        }
+        AbstractService.prototype = {
+            strRequest: null,
+            oRequest: null,
+            oFilter: null,
+            constructor: AbstractService,
+            addRequest: function (oRequest) {
+            },
+            addFilter: function (oFilter) {
+            },
+            toString: function () {
+            }
+        };
+        return AbstractService;
+    }(UtilsLoggerByDefault);
+    FormatsXLS = function (Logger, RequestHeader, Request, AbstractService) {
+        function XLS(options) {
+            if (!(this instanceof XLS)) {
+                throw new TypeError('XLS constructor cannot be called as a function.');
+            }
+            this.options = {
+                srsName: 'EPSG:4326',
+                maximumResponses: 25
+            };
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    if (options[opt]) {
+                        this.options[opt] = options[opt];
+                    }
+                }
+            }
+        }
+        XLS.VERSION = '1.2';
+        XLS.prototype = {
+            requestString: null,
+            namespace: false,
+            oService: null,
+            constructor: XLS,
+            template: '<?xml version="1.0" encoding="UTF-8"?>\n' + '<XLS version="__VERSION__"\n' + '__NAMESPACE__ \n' + '__SCHEMALOCATION__>\n' + '__REQUESTHEADER__\n' + '__REQUEST__\n' + '</XLS>\n',
+            namespaceByDefault: function () {
+                var ns = [
+                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"',
+                    'xmlns:xls="http://www.opengis.net/xls"',
+                    'xmlns:gml="http://www.opengis.net/gml"'
+                ];
+                return ns.join(' ');
+            },
+            schemaLocationByDefault: function () {
+                return 'xsi:schemaLocation="http://www.opengis.net/xls http://schemas.opengis.net/ols/1.2/olsAll.xsd"';
+            },
+            setService: function (oService) {
+                if (!oService) {
+                    return;
+                }
+                if (oService instanceof AbstractService) {
+                    this.oService = oService;
+                } else {
+                }
+            },
+            getService: function () {
+                return this.oService;
+            }
+        };
+        XLS.prototype.addNamespace = function (ns, request) {
+            var keyNS = ns.key;
+            var bFound = false;
+            var allNS = this.namespaceByDefault().split(' ');
+            for (var index = 0; index < allNS.length; index++) {
+                var element = allNS[index];
+                var map = element.split('=');
+                var key = map[0];
+                if (key === 'xmlns:' + keyNS) {
+                    bFound = true;
+                    break;
+                }
+            }
+            if (!bFound) {
+                return request;
+            }
+            var regex;
+            var subst;
+            regex = /<(\w+[\s>])/g;
+            subst = '<' + keyNS + ':$1';
+            request = request.replace(regex, subst);
+            regex = /<\/(\w+[\s>])/g;
+            subst = '</' + keyNS + ':$1';
+            request = request.replace(regex, subst);
+            return request;
+        };
+        XLS.prototype.build = function () {
+            var bService = this.getService() ? true : false;
+            var template = '';
+            template = this.template;
+            template = template.replace(/__VERSION__/g, XLS.VERSION);
+            template = template.replace(/__NAMESPACE__/g, this.namespaceByDefault);
+            template = template.replace(/__SCHEMALOCATION__/g, this.schemaLocationByDefault);
+            var oHeader = new RequestHeader({ srsName: this.options.srsName });
+            template = template.replace(/__REQUESTHEADER__/g, oHeader.toString());
+            var oRequest = new Request({
+                maximumResponses: this.options.maximumResponses,
+                version: XLS.VERSION,
+                methodName: bService ? this.getService().CLASSTYPE : null
+            });
+            template = template.replace(/__REQUEST__/g, oRequest.toString());
+            if (bService) {
+                template = template.replace(/<!-- __REQUESTSERVICE__ -->/g, this.getService().toString());
+            }
+            if (!template) {
+                return;
+            }
+            if (this.namespace) {
+                template = this.addNamespace({
+                    key: 'xls',
+                    url: 'http://www.opengis.net/xls'
+                }, template);
+            }
+            this.requestString = template;
+            return this.requestString;
+        };
+        return XLS;
+    }(UtilsLoggerByDefault, FormatsXLSRequestHeader, FormatsXLSRequest, FormatsXLSAbstractService);
+    FormatsXLSLocationUtilityServiceModelAddress = function (Gp, Logger) {
+        function Address(options) {
+            if (!(this instanceof Address)) {
+                throw new TypeError('Address constructor cannot be called as a function.');
+            }
+            this.options = options || {
+                location: {},
+                type: ['StreetAddress'],
+                filter: {}
+            };
+            if (!options.location) {
+                throw new Error('l\'option \'location\' n\'est pas renseignée !');
+            }
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+        }
+        Address.prototype = {
+            constructor: Address,
+            requestString: null,
+            template: {
+                address: '<Address countryCode="__COUNTRYCODE__">' + '__LOCATION__' + '__PLACE__' + '__POSTALCODE__' + '__ENVELOPE__' + '</Address>',
+                location: {
+                    freeFormAddress: '<freeFormAddress>__FREEFORMADDRESSVALUE__</freeFormAddress>',
+                    streetAddress: {
+                        container: '<StreetAddress>' + '__STREET__' + '__BUILDING__' + '</StreetAddress>',
+                        building: '<Building number="__BUILDINGVALUE__"/>',
+                        street: '<Street>__STREETVALUE__</Street>'
+                    }
+                },
+                place: '<Place type="__PLACETYPE__">__PLACEVALUE__</Place>',
+                postalCode: '<PostalCode>__POSTALCODEVALUE__</PostalCode>',
+                envelope: '<gml:Envelope>' + '<gml:lowerCorner>__LEFT__ __BOTTOM__</gml:lowerCorner>' + '<gml:upperCorner>__RIGHT__ __TOP__</gml:upperCorner>' + '</gml:Envelope>'
+            }
+        };
+        Address.prototype.toString = function () {
+            var template = null;
+            template = this.template.address;
+            template = template.replace(/__COUNTRYCODE__/g, this.options.type);
+            if (typeof this.options.location === 'string') {
+                var tmplFreeFormAddress = this.template.location.freeFormAddress;
+                tmplFreeFormAddress = tmplFreeFormAddress.replace(/__FREEFORMADDRESSVALUE__/g, this.options.location);
+                template = template.replace(/__LOCATION__/g, tmplFreeFormAddress);
+            } else {
+                var tmplBuilding = '';
+                var tmplStreet = '';
+                if (this.options.location.number) {
+                    tmplBuilding = this.template.location.streetAddress.building;
+                    tmplBuilding = tmplBuilding.replace(/__BUILDINGVALUE__/g, this.options.location.number);
+                }
+                if (this.options.location.street) {
+                    tmplStreet = this.template.location.streetAddress.street;
+                    tmplStreet = tmplStreet.replace(/__STREETVALUE__/g, this.options.location.street);
+                }
+                var tmplStreetAddress = this.template.location.streetAddress.container;
+                tmplStreetAddress = tmplStreetAddress.replace(/__STREET__/g, tmplStreet);
+                tmplStreetAddress = tmplStreetAddress.replace(/__BUILDING__/g, tmplBuilding);
+                template = template.replace(/__LOCATION__/g, tmplStreetAddress);
+            }
+            var tmplPostalCode = '';
+            if (this.options.location.postalCode) {
+                tmplPostalCode = this.template.postalCode;
+                tmplPostalCode = tmplPostalCode.replace(/__POSTALCODEVALUE__/g, this.options.location.postalCode);
+            }
+            var tmplEnvelope = '';
+            if (this.options.filter) {
+                var bbox = this.options.filter.bbox;
+                if (bbox) {
+                    tmplEnvelope = this.template.envelope;
+                    tmplEnvelope = tmplEnvelope.replace(/__LEFT__/g, bbox.left);
+                    tmplEnvelope = tmplEnvelope.replace(/__BOTTOM__/g, bbox.bottom);
+                    tmplEnvelope = tmplEnvelope.replace(/__RIGHT__/g, bbox.right);
+                    tmplEnvelope = tmplEnvelope.replace(/__TOP__/g, bbox.top);
+                }
+            }
+            var Places = [];
+            var tmplPlace = '';
+            if (this.options.filter) {
+                var filters = this.options.filter;
+                for (var filter in filters) {
+                    if (filter === 'bbox') {
+                        continue;
+                    }
+                    tmplPlace = this.template.place;
+                    tmplPlace = tmplPlace.replace(/__PLACETYPE__/g, filter);
+                    tmplPlace = tmplPlace.replace(/__PLACEVALUE__/g, filters[filter]);
+                    Places.push(tmplPlace);
+                }
+            }
+            var tmplPlaceCity = '';
+            if (this.options.location.city) {
+                tmplPlaceCity = this.template.place;
+                tmplPlaceCity = tmplPlaceCity.replace(/__PLACETYPE__/g, 'Municipality');
+                tmplPlaceCity = tmplPlaceCity.replace(/__PLACEVALUE__/g, this.options.location.city);
+                Places.push(tmplPlaceCity);
+            }
+            template = template.replace(/__POSTALCODE__/g, tmplPostalCode);
+            template = template.replace(/__PLACE__/g, Places.join('\n'));
+            template = template.replace(/__ENVELOPE__/g, tmplEnvelope);
+            this.requestString = template;
+            return this.requestString;
+        };
+        return Address;
+    }(Gp, UtilsLoggerByDefault);
+    FormatsXLSLocationUtilityServiceGeocodeFilterExtension = function (Logger) {
+        function GeocodeFilterExtension() {
+            if (!(this instanceof GeocodeFilterExtension)) {
+                throw new TypeError('GeocodeFilterExtension constructor cannot be called as a function.');
+            }
+            this.filters = [];
+        }
+        GeocodeFilterExtension.prototype = {
+            constructor: GeocodeFilterExtension,
+            addFilterExtensions: function (oGeocodeLocation) {
+                if (oGeocodeLocation) {
+                    this.filters.push(oGeocodeLocation);
+                }
+            },
+            getNames: function () {
+                var names = [];
+                for (var idx in this.filters) {
+                    names.push(this.filters[idx].CLASSNAME);
+                }
+                return names;
+            },
+            getFilter: function (name) {
+                var filter = null;
+                for (var idx in this.filters) {
+                    if (this.filters[idx].CLASSNAME == name) {
+                        filter = this.filters[idx];
+                    }
+                }
+                return filter;
+            },
+            getFilters: function () {
+                return this.filters;
+            },
+            getAttributs: function (name) {
+                var attributs = [];
+                for (var idx in this.filters) {
+                    if (this.filters[idx].CLASSNAME == name) {
+                        attributs = this.filters[idx].attributesList;
+                    }
+                }
+                return attributs;
+            },
+            setPlaceAttributs: function (name, options) {
+                var filter = this.getFilter(name);
+                var attributs = this.getAttributs(name);
+                for (var idx in attributs) {
+                    var value = attributs[idx];
+                    if (options[value]) {
+                        filter.placeAttributes[value] = options[value];
+                    }
+                }
+            },
+            getPlaceAttributs: function (name) {
+                var places = {};
+                for (var idx in this.filters) {
+                    if (this.filters[idx].CLASSNAME == name) {
+                        places = this.filters[idx].placeAttributes;
+                    }
+                }
+                return places;
+            }
+        };
+        return GeocodeFilterExtension;
+    }(UtilsLoggerByDefault);
+    FormatsXLSLocationUtilityServiceGeocodeRequest = function (Logger, Address, GeocodeFilterExtension) {
+        function GeocodeRequest(options) {
+            if (!(this instanceof GeocodeRequest)) {
+                throw new TypeError('GeocodeRequest constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+            this.CLASSNAME = 'GeocodeRequest';
+        }
+        GeocodeRequest.prototype = {
+            strRequest: null,
+            oAddress: null,
+            oFilter: null,
+            template: '<GeocodeRequest returnFreeForm="__RETURNFREEFORM__">' + '__ADDRESS__' + '</GeocodeRequest>',
+            addAddress: function (oAddress) {
+                if (oAddress instanceof Address) {
+                    this.oAddress = oAddress;
+                }
+            },
+            addFilter: function (oFilter) {
+                if (oFilter instanceof GeocodeFilterExtension) {
+                    this.oFilter = oFilter;
+                }
+            },
+            constructor: GeocodeRequest,
+            toString: function () {
+                var template = '';
+                template = this.template;
+                if (!this.oAddress) {
+                    var settings = {};
+                    settings.location = this.options.location;
+                    settings.type = this.options.filterOptions.type || ['StreetAddress'];
+                    settings.filter = this.options.filterOptions;
+                    delete settings.filter.type;
+                    if (this.oFilter) {
+                        settings.filter = {};
+                        for (var idx in settings.type) {
+                            var filter = settings.type[idx];
+                            var oFilter = this.oFilter.getFilter(filter);
+                            if (!oFilter) {
+                                continue;
+                            }
+                            var mFilter = this.options.filterOptions;
+                            var attributs = oFilter.attributesList;
+                            for (var idxe = 0; idxe < attributs.length; idxe++) {
+                                var key = attributs[idxe];
+                                if (mFilter[key]) {
+                                    var matchingKey = oFilter.serviceAttributes[idxe];
+                                    oFilter.placeAttributes[matchingKey] = mFilter[key];
+                                }
+                            }
+                            var places = oFilter.placeAttributes;
+                            for (var kplace in places) {
+                                if (places.hasOwnProperty(kplace)) {
+                                    settings.filter[kplace] = places[kplace];
+                                }
+                            }
+                        }
+                    }
+                    this.oAddress = new Address(settings);
+                    if (!this.oAddress) {
+                        throw new Error('La construction de l\'adresse n\'est pas correctement definie !?');
+                    }
+                }
+                template = template.replace(/__ADDRESS__/g, this.oAddress.toString());
+                template = template.replace(/__RETURNFREEFORM__/g, this.options.returnFreeForm ? 'true' : 'false');
+                this.strRequest = template;
+                return this.strRequest;
+            }
+        };
+        return GeocodeRequest;
+    }(UtilsLoggerByDefault, FormatsXLSLocationUtilityServiceModelAddress, FormatsXLSLocationUtilityServiceGeocodeFilterExtension);
+    FormatsXLSLocationUtilityServiceModelPosition = function (Logger) {
+        function Position(options) {
+            if (!(this instanceof Position)) {
+                throw new TypeError('Position constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            if (!options.position) {
+                throw new Error('l\'option \'position\' n\'est pas renseignée !');
+            }
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+        }
+        Position.prototype = {
+            constructor: Position,
+            requestString: null,
+            template: {
+                position: '<Position>' + '__GMLPOINT__' + '__GMLFILTER__' + '</Position>',
+                gml: {
+                    point: '<gml:Point xmlns:gml="http://www.opengis.net/gml"><gml:pos>__X__ __Y__</gml:pos></gml:Point>',
+                    pos: null,
+                    filter: {
+                        bbox: '<gml:Envelope xmlns:gml="http://www.opengis.net/gml">' + '<gml:lowerCorner>__LEFT__ __BOTTOM__</gml:lowerCorner>' + '<gml:upperCorner>__RIGHT__ __TOP__</gml:upperCorner>' + '</gml:Envelope>',
+                        circle: '<gml:CircleByCenterPoint xmlns:gml="http://www.opengis.net/gml"><gml:pos>__X__ __Y__</gml:pos><gml:radius>__RADIUS__</gml:radius></gml:CircleByCenterPoint>',
+                        polygon: '<gml:Polygon xmlns:gml="http://www.opengis.net/gml"><gml:exterior><gml:LinearRing><gml:posList>__XY__</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon>',
+                        multipolygon: null
+                    }
+                }
+            }
+        };
+        Position.prototype.toString = function () {
+            var template = this.template.position;
+            var tmplGmlPoint = this.template.gml.point;
+            tmplGmlPoint = tmplGmlPoint.replace(/__X__/g, this.options.position.x);
+            tmplGmlPoint = tmplGmlPoint.replace(/__Y__/g, this.options.position.y);
+            var tmplGmlFilter = '';
+            if (this.options.filter) {
+                var filter = this.options.filter;
+                for (var name in filter) {
+                    switch (name) {
+                    case 'circle':
+                        tmplGmlFilter = this.template.gml.filter[name];
+                        tmplGmlFilter = tmplGmlFilter.replace(/__X__/g, filter[name].x);
+                        tmplGmlFilter = tmplGmlFilter.replace(/__Y__/g, filter[name].y);
+                        tmplGmlFilter = tmplGmlFilter.replace(/__RADIUS__/g, filter[name].radius);
+                        break;
+                    case 'bbox':
+                        tmplGmlFilter = this.template.gml.filter[name];
+                        tmplGmlFilter = tmplGmlFilter.replace(/__LEFT__/g, filter[name].left);
+                        tmplGmlFilter = tmplGmlFilter.replace(/__BOTTOM__/g, filter[name].bottom);
+                        tmplGmlFilter = tmplGmlFilter.replace(/__RIGHT__/g, filter[name].right);
+                        tmplGmlFilter = tmplGmlFilter.replace(/__TOP__/g, filter[name].top);
+                        break;
+                    case 'polygon':
+                        tmplGmlFilter = this.template.gml.filter[name];
+                        var strPoints = '';
+                        var lstPoints = filter[name];
+                        for (var i = 0; i < lstPoints.length; i++) {
+                            var coord = lstPoints[i];
+                            if (Array.isArray(coord)) {
+                                break;
+                            }
+                            if (coord.x && coord.y || (coord.x === 0 || coord.y === 0)) {
+                                strPoints += coord.x + ' ' + coord.y;
+                            }
+                            if (lstPoints.length !== i + 1) {
+                                strPoints += ' ';
+                            }
+                        }
+                        tmplGmlFilter = tmplGmlFilter.replace(/__XY__/g, strPoints);
+                        break;
+                    case 'multipolygon':
+                        break;
+                    default:
+                    }
+                }
+            }
+            template = template.replace(/__GMLPOINT__/g, tmplGmlPoint);
+            template = template.replace(/__GMLFILTER__/g, tmplGmlFilter);
+            this.requestString = template;
+            return this.requestString;
+        };
+        return Position;
+    }(UtilsLoggerByDefault);
+    FormatsXLSLocationUtilityServiceModelPreference = function (Logger) {
+        function Preference(type) {
+            if (!(this instanceof Preference)) {
+                throw new TypeError('Preference constructor cannot be called as a function.');
+            }
+            this.type = type;
+        }
+        Preference.prototype = {
+            constructor: Preference,
+            requestString: null,
+            template: '<ReverseGeocodePreference>__TYPE__</ReverseGeocodePreference>'
+        };
+        Preference.prototype.toString = function () {
+            var Preferences = [];
+            var tmplPreference = '';
+            for (var idx = 0; idx < this.type.length; idx++) {
+                tmplPreference = this.template;
+                tmplPreference = tmplPreference.replace(/__TYPE__/g, this.type[idx]);
+                Preferences.push(tmplPreference);
+            }
+            this.strRequest = Preferences.join('\n');
+            return this.strRequest;
+        };
+        return Preference;
+    }(UtilsLoggerByDefault);
+    FormatsXLSLocationUtilityServiceReverseGeocodeRequest = function (Logger, Position, Preference) {
+        function ReverseGeocodeRequest(options) {
+            if (!(this instanceof ReverseGeocodeRequest)) {
+                throw new TypeError('ReverseGeocodeRequest constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+            this.CLASSNAME = 'ReverseGeocodeRequest';
+        }
+        ReverseGeocodeRequest.prototype = {
+            strRequest: null,
+            oPosition: null,
+            oPreference: null,
+            constructor: ReverseGeocodeRequest,
+            template: '<ReverseGeocodeRequest returnFreeForm="__RETURNFREEFORM__">' + '__POSITION__' + '__PREFERENCE__' + '</ReverseGeocodeRequest>',
+            addPosition: function (oPosition) {
+                if (oPosition instanceof Position) {
+                    this.oPosition = oPosition;
+                }
+            },
+            addPreferences: function (oPreference) {
+                if (oPreference instanceof Preference) {
+                    this.oPreference = oPreference;
+                }
+            },
+            toString: function () {
+                var template = '';
+                template = this.template;
+                if (!this.oPreference) {
+                    this.oPreference = new Preference(this.options.filterOptions.type || ['StreetAddress']);
+                    if (!this.oPreference) {
+                        throw new Error('Les preferences ne sont pas definies !?');
+                    }
+                }
+                template = template.replace(/__PREFERENCE__/g, this.oPreference.toString());
+                if (!this.oPosition) {
+                    var settings = {
+                        position: this.options.position,
+                        filter: {}
+                    };
+                    if (this.options.filterOptions) {
+                        settings.filter = this.options.filterOptions;
+                        delete settings.filter.type;
+                    }
+                    this.oPosition = new Position(settings);
+                    if (!this.oPosition) {
+                        throw new Error('La position et ses filtres ne sont pas definis !?');
+                    }
+                }
+                template = template.replace(/__POSITION__/g, this.oPosition.toString());
+                template = template.replace(/__RETURNFREEFORM__/g, this.options.returnFreeForm ? 'true' : 'false');
+                this.strRequest = template;
+                return this.strRequest;
+            }
+        };
+        return ReverseGeocodeRequest;
+    }(UtilsLoggerByDefault, FormatsXLSLocationUtilityServiceModelPosition, FormatsXLSLocationUtilityServiceModelPreference);
+    FormatsXLSLocationUtilityService = function (Logger, AbstractService, GeocodeRequest, ReverseGeocodeRequest, GeocodeFilterExtension) {
+        function LocationUtilityService(options) {
+            if (!(this instanceof LocationUtilityService)) {
+                throw new TypeError('LocationUtilityService constructor cannot be called as a function.');
+            }
+            this.CLASSNAME = 'LocationUtilityService';
+            this.CLASSTYPE = null;
+            AbstractService.apply(this, arguments);
+            if (this.options) {
+                this.CLASSTYPE = this.options.location ? 'GeocodeRequest' : this.options.position ? 'ReverseGeocodeRequest' : null;
+            }
+        }
+        LocationUtilityService.prototype = Object.create(AbstractService.prototype, {});
+        LocationUtilityService.prototype.constructor = LocationUtilityService;
+        LocationUtilityService.prototype.addRequest = function (oLUSRequest) {
+            this.CLASSTYPE = oLUSRequest.CLASSNAME;
+            switch (this.CLASSTYPE) {
+            case 'GeocodeRequest':
+            case 'ReverseGeocodeRequest':
+                this.oRequest = oLUSRequest;
+                break;
+            default:
+                throw new Error('Ce n\'est pas un objet de type \'LUS Request\' !?');
+            }
+        };
+        LocationUtilityService.prototype.addFilter = function (oFilter) {
+            if (oFilter instanceof GeocodeFilterExtension) {
+                this.oFilter = oFilter;
+            }
+        };
+        LocationUtilityService.prototype.toString = function () {
+            if (!this.oRequest) {
+                if (!this.options) {
+                    throw new Error('Les options ne sont pas renseignées, impossible de construire la requête !');
+                }
+                if (this.CLASSTYPE === 'GeocodeRequest') {
+                    var settingsDirect = {
+                        location: this.options.location,
+                        returnFreeForm: this.options.returnFreeForm,
+                        filterOptions: this.options.filterOptions || {}
+                    };
+                    this.oRequest = new GeocodeRequest(settingsDirect);
+                    if (this.oFilter) {
+                        this.oRequest.addFilter(this.oFilter);
+                    }
+                } else if (this.CLASSTYPE === 'ReverseGeocodeRequest') {
+                    var settingsInv = {
+                        position: this.options.position,
+                        returnFreeForm: this.options.returnFreeForm,
+                        filterOptions: this.options.filterOptions || {}
+                    };
+                    this.oRequest = new ReverseGeocodeRequest(settingsInv);
+                } else {
+                }
+            }
+            if (!this.oRequest) {
+                throw new Error('Type de Geocodage indefini !');
+            }
+            this.strRequest = this.oRequest.toString();
+            return this.strRequest;
+        };
+        return LocationUtilityService;
+    }(UtilsLoggerByDefault, FormatsXLSAbstractService, FormatsXLSLocationUtilityServiceGeocodeRequest, FormatsXLSLocationUtilityServiceReverseGeocodeRequest, FormatsXLSLocationUtilityServiceGeocodeFilterExtension);
+    ServicesGeocodeRequestGeocodeLocation = function () {
+        function GeocodeLocation() {
+            if (!(this instanceof GeocodeLocation)) {
+                throw new TypeError('GeocodeLocation constructor cannot be called as a function.');
+            }
+            this.placeAttributes = {};
+            this.attributesList = [];
+            this.serviceAttributes = [];
+        }
+        GeocodeLocation.prototype = { constructor: GeocodeLocation };
+        return GeocodeLocation;
+    }();
+    ServicesGeocodeRequestModelStreetAddress = function (GeocodeLocation) {
+        function StreetAddress() {
+            if (!(this instanceof StreetAddress)) {
+                throw new TypeError('StreetAddress constructor cannot be called as a function.');
+            }
+            GeocodeLocation.apply(this, arguments);
+            this.CLASSNAME = 'StreetAddress';
+            this.attributesList = [
+                'bbox',
+                'ID',
+                'IDTR',
+                'quality',
+                'territory',
+                'commune',
+                'department',
+                'insee',
+                'municipality'
+            ];
+            this.serviceAttributes = [
+                'bbox',
+                'ID',
+                'IDTR',
+                'Qualite',
+                'Territoire',
+                'Commune',
+                'Departement',
+                'INSEE',
+                'Municipality'
+            ];
+        }
+        StreetAddress.prototype = Object.create(GeocodeLocation.prototype);
+        StreetAddress.prototype.constructor = StreetAddress;
+        return StreetAddress;
+    }(ServicesGeocodeRequestGeocodeLocation);
+    ServicesGeocodeRequestModelPositionOfInterest = function (GeocodeLocation) {
+        function PositionOfInterest() {
+            if (!(this instanceof PositionOfInterest)) {
+                throw new TypeError('PositionOfInterest constructor cannot be called as a function.');
+            }
+            GeocodeLocation.apply(this, arguments);
+            this.CLASSNAME = 'PositionOfInterest';
+            this.attributesList = [
+                'bbox',
+                'importance',
+                'nature',
+                'territory',
+                'commune',
+                'department',
+                'insee',
+                'municipality'
+            ];
+            this.serviceAttributes = [
+                'bbox',
+                'Importance',
+                'Nature',
+                'Territoire',
+                'Commune',
+                'Departement',
+                'INSEE',
+                'Municipality'
+            ];
+        }
+        PositionOfInterest.prototype = Object.create(GeocodeLocation.prototype);
+        PositionOfInterest.prototype.constructor = PositionOfInterest;
+        return PositionOfInterest;
+    }(ServicesGeocodeRequestGeocodeLocation);
+    ServicesGeocodeRequestModelCadastralParcel = function (GeocodeLocation) {
+        function CadastralParcel() {
+            if (!(this instanceof CadastralParcel)) {
+                throw new TypeError('CadastralParcel constructor cannot be called as a function.');
+            }
+            GeocodeLocation.apply(this, arguments);
+            this.CLASSNAME = 'CadastralParcel';
+            this.attributesList = [
+                'absorbedCity',
+                'sheet',
+                'number',
+                'section',
+                'commune',
+                'department',
+                'insee',
+                'municipality',
+                'origin'
+            ];
+            this.serviceAttributes = [
+                'CommuneAbsorbee',
+                'Feuille',
+                'Numero',
+                'Section',
+                'Commune',
+                'Departement',
+                'INSEE',
+                'Municipality',
+                'Type'
+            ];
+        }
+        CadastralParcel.prototype = Object.create(GeocodeLocation.prototype);
+        CadastralParcel.prototype.constructor = CadastralParcel;
+        return CadastralParcel;
+    }(ServicesGeocodeRequestGeocodeLocation);
+    ServicesGeocodeRequestModelAdministratif = function (GeocodeLocation) {
+        function Administratif() {
+            if (!(this instanceof Administratif)) {
+                throw new TypeError('Administratif constructor cannot be called as a function.');
+            }
+            GeocodeLocation.apply(this, arguments);
+            this.CLASSNAME = 'Administratif';
+            this.attributesList = [
+                'bbox',
+                'prefecture',
+                'inseeRegion',
+                'inseeDepartment',
+                'municipality'
+            ];
+            this.serviceAttributes = [
+                'bbox',
+                'Prefecture',
+                'InseeRegion',
+                'InseeDepartement',
+                'Municipality'
+            ];
+        }
+        Administratif.prototype = Object.create(GeocodeLocation.prototype);
+        Administratif.prototype.constructor = Administratif;
+        return Administratif;
+    }(ServicesGeocodeRequestGeocodeLocation);
+    ServicesGeocodeRequestDirectGeocodeRequestFactory = function (Logger, XLS, LocationUtilityService, GeocodeFilterExtension, StreetAddress, PositionOfInterest, CadastralParcel, Administratif) {
+        var DirectGeocodeRequestFactory = {
+            build: function (options) {
+                var request = null;
+                var oFilter = new GeocodeFilterExtension();
+                oFilter.addFilterExtensions(new Administratif());
+                oFilter.addFilterExtensions(new StreetAddress());
+                oFilter.addFilterExtensions(new PositionOfInterest());
+                oFilter.addFilterExtensions(new CadastralParcel());
+                var oLUS = new LocationUtilityService({
+                    location: options.location,
+                    returnFreeForm: options.returnFreeForm,
+                    filterOptions: options.filterOptions
+                });
+                oLUS.addFilter(oFilter);
+                var oXLS = new XLS({
+                    srsName: options.srs,
+                    maximumResponses: options.maximumResponses
+                });
+                oXLS.namespace = true;
+                oXLS.setService(oLUS);
+                request = oXLS.build();
+                if (options.httpMethod == 'GET') {
+                    var myRequest = 'qxml=' + encodeURIComponent(request).replace(/\-/g, '%2D').replace(/\_/g, '%5F').replace(/\./g, '%2E').replace(/\!/g, '%21').replace(/\~/g, '%7E').replace(/\*/g, '%2A').replace(/\'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
+                    request = myRequest;
+                }
+                return request;
+            }
+        };
+        return DirectGeocodeRequestFactory;
+    }(UtilsLoggerByDefault, FormatsXLS, FormatsXLSLocationUtilityService, FormatsXLSLocationUtilityServiceGeocodeFilterExtension, ServicesGeocodeRequestModelStreetAddress, ServicesGeocodeRequestModelPositionOfInterest, ServicesGeocodeRequestModelCadastralParcel, ServicesGeocodeRequestModelAdministratif);
+    ServicesGeocodeResponseModelGeocodeResponse = function () {
+        function GeocodeResponse() {
+            if (!(this instanceof GeocodeResponse)) {
+                throw new TypeError('GeocodeResponse constructor cannot be called as a function.');
+            }
+            this.locations = [];
+        }
+        GeocodeResponse.prototype = { constructor: GeocodeResponse };
+        return GeocodeResponse;
+    }();
+    ServicesGeocodeResponseModelGeocodedLocation = function () {
+        function GeocodedLocation() {
+            if (!(this instanceof GeocodedLocation)) {
+                throw new TypeError('GeocodedLocation constructor cannot be called as a function.');
+            }
+            this.position = {
+                x: null,
+                y: null
+            };
+            this.matchType = null;
+            this.placeAttributes = {};
+            this.type = null;
+        }
+        GeocodedLocation.prototype = { constructor: GeocodedLocation };
+        return GeocodedLocation;
+    }();
+    ServicesGeocodeResponseModelDirectGeocodedLocation = function (GeocodedLocation) {
+        function DirectGeocodedLocation() {
+            if (!(this instanceof DirectGeocodedLocation)) {
+                throw new TypeError('DirectGeocodedLocation constructor cannot be called as a function.');
+            }
+            GeocodedLocation.apply(this, arguments);
+            this.CLASSNAME = 'DirectGeocodedLocation';
+            this.accuracy = null;
+        }
+        DirectGeocodedLocation.prototype = Object.create(GeocodedLocation.prototype);
+        DirectGeocodedLocation.prototype.constructor = DirectGeocodedLocation;
+        return DirectGeocodedLocation;
+    }(ServicesGeocodeResponseModelGeocodedLocation);
+    ServicesGeocodeFormatsDirectGeocodeResponseReader = function (Logger, MR, ErrSrv, GeocodeResponse, DirectGeocodedLocation) {
+        var DirectGeocodeResponseReader = {};
+        DirectGeocodeResponseReader.VERSION = '1.2';
+        DirectGeocodeResponseReader.NAMESPACES = {
+            xmlns: 'http://www.opengis.net/xls',
+            gml: 'http://www.opengis.net/gml',
+            xls: 'http://www.opengis.net/xls',
+            xlsext: 'http://www.opengis.net/xlsext',
+            xsi: 'http://www.w3.org/2001/XMLSchema-instance'
+        };
+        DirectGeocodeResponseReader.SCHEMALOCATION = 'http://wxs.ign.fr/schemas/olsAll.xsd';
+        DirectGeocodeResponseReader.DEFAULTPREFIX = 'xls';
+        DirectGeocodeResponseReader.READERS = {
+            xls: {
+                XLS: function (root) {
+                    var geocodeResponse = new GeocodeResponse();
+                    __checkServiceAttributes(root);
+                    __getChildNodes(root, geocodeResponse);
+                    return geocodeResponse;
+                },
+                GeocodedAddress: function (node, geocodeResponse) {
+                    var geocodedLocation = new DirectGeocodedLocation();
+                    __getChildNodes(node, geocodedLocation);
+                    if (geocodeResponse && Array.isArray(geocodeResponse.locations)) {
+                        geocodeResponse.locations.push(geocodedLocation);
+                    }
+                },
+                GeocodeMatchCode: function (node, geocodedLocation) {
+                    var acc = node.getAttribute('accuracy');
+                    if (acc && geocodedLocation) {
+                        geocodedLocation.accuracy = parseFloat(acc);
+                    }
+                    var matchType = node.getAttribute('matchType');
+                    if (matchType && geocodedLocation) {
+                        geocodedLocation.matchType = matchType;
+                    }
+                },
+                Address: function (node, geocodedLocation) {
+                    var countrycode = node.getAttribute('countryCode');
+                    if (geocodedLocation && countrycode) {
+                        geocodedLocation.type = countrycode;
+                    }
+                    __getChildNodes(node, geocodedLocation);
+                },
+                freeFormAddress: function (node, geocodedLocation) {
+                    if (geocodedLocation && geocodedLocation.hasOwnProperty('placeAttributes')) {
+                        geocodedLocation.placeAttributes.freeform = __getChildValue(node);
+                    }
+                },
+                Building: function (node, geocodedLocation) {
+                    var num = node.getAttribute('number');
+                    if (geocodedLocation && geocodedLocation.hasOwnProperty('placeAttributes')) {
+                        if (num) {
+                            geocodedLocation.placeAttributes.number = num;
+                        } else if (node.getAttribute('buildingName')) {
+                            geocodedLocation.placeAttributes.number = node.getAttribute('buildingName');
+                        } else if (node.getAttribute('subdivision')) {
+                            geocodedLocation.placeAttributes.number = node.getAttribute('subdivision');
+                        }
+                    }
+                },
+                Street: function (node, geocodedLocation) {
+                    if (geocodedLocation && geocodedLocation.hasOwnProperty('placeAttributes')) {
+                        if (geocodedLocation.type === 'StreetAddress') {
+                            geocodedLocation.placeAttributes.street = __getChildValue(node);
+                        } else if (geocodedLocation.type === 'CadastralParcel') {
+                            geocodedLocation.placeAttributes.cadastralParcel = __getChildValue(node);
+                        }
+                    }
+                },
+                Place: function (node, geocodedLocation) {
+                    var placeType = node.getAttribute('type');
+                    var placeName = __getChildValue(node);
+                    if (geocodedLocation && geocodedLocation.hasOwnProperty('placeAttributes')) {
+                        if (placeType === 'Municipality') {
+                            geocodedLocation.placeAttributes.municipality = placeName;
+                        } else if (placeType === 'Bbox') {
+                            var values = placeName.split(';');
+                            if (values.length === 4) {
+                                geocodedLocation.placeAttributes.bbox = {
+                                    left: parseFloat(values[0]),
+                                    right: parseFloat(values[2]),
+                                    top: parseFloat(values[1]),
+                                    bottom: parseFloat(values[3])
+                                };
+                            }
+                        } else if (placeType === 'Commune') {
+                            geocodedLocation.placeAttributes.commune = placeName;
+                        } else if (placeType === 'Departement') {
+                            geocodedLocation.placeAttributes.department = placeName;
+                        } else if (placeType === 'INSEE') {
+                            geocodedLocation.placeAttributes.insee = placeName;
+                        } else if (placeType === 'Qualite') {
+                            geocodedLocation.placeAttributes.quality = placeName;
+                        } else if (placeType === 'Territoire') {
+                            geocodedLocation.placeAttributes.territory = placeName;
+                        } else if (placeType === 'ID') {
+                            geocodedLocation.placeAttributes.ID = placeName;
+                        } else if (placeType === 'ID_TR') {
+                            geocodedLocation.placeAttributes.IDTR = placeName;
+                        } else if (placeType === 'Importance') {
+                            geocodedLocation.placeAttributes.importance = parseInt(placeName, 10);
+                        } else if (placeType === 'Nature') {
+                            geocodedLocation.placeAttributes.nature = placeName;
+                        } else if (placeType === 'Numero') {
+                            geocodedLocation.placeAttributes.number = placeName;
+                        } else if (placeType === 'Feuille') {
+                            geocodedLocation.placeAttributes.sheet = placeName;
+                        } else if (placeType === 'Section') {
+                            geocodedLocation.placeAttributes.section = placeName;
+                        } else if (placeType === 'CommuneAbsorbee') {
+                            geocodedLocation.placeAttributes.absorbedCity = placeName;
+                        } else if (placeType === 'Arrondissement') {
+                            if (placeName) {
+                                geocodedLocation.placeAttributes.arrondissement = placeName;
+                            }
+                        } else if (placeType === 'Type') {
+                            geocodedLocation.placeAttributes.origin = placeName;
+                        } else if (placeType === 'Prefecture') {
+                            geocodedLocation.placeAttributes.prefecture = placeName;
+                        } else if (placeType === 'InseeRegion') {
+                            geocodedLocation.placeAttributes.inseeRegion = placeName;
+                        } else if (placeType === 'InseeDepartment') {
+                            geocodedLocation.placeAttributes.inseeDepartment = placeName;
+                        }
+                    }
+                },
+                PostalCode: function (node, geocodedLocation) {
+                    if (geocodedLocation && geocodedLocation.hasOwnProperty('placeAttributes')) {
+                        geocodedLocation.placeAttributes.postalCode = __getChildValue(node);
+                    }
+                },
+                Error: function (node) {
+                    var srvMess = node.getAttribute('message');
+                    var errorCode = node.getAttribute('errorCode');
+                    var message = MR.getMessage('SERVICE_RESPONSE_EXCEPTION', '(' + errorCode + ') : ' + srvMess);
+                    throw new ErrSrv({
+                        message: message,
+                        type: ErrSrv.TYPE_SRVERR
+                    });
+                }
+            },
+            gml: {
+                pos: function (node, geocodedLocation) {
+                    var pos = __getChildValue(node);
+                    if (geocodedLocation && pos) {
+                        geocodedLocation.position = {
+                            x: parseFloat(pos.split(' ')[0]),
+                            y: parseFloat(pos.split(' ')[1])
+                        };
+                    }
+                }
+            },
+            ExceptionReport: function (node) {
+                var response = {};
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (child.nodeName === 'Exception') {
+                            response.exceptionReport = DirectGeocodeResponseReader.READERS['Exception'](child);
+                        }
+                    }
+                }
+                return response;
+            },
+            Exception: function (node) {
+                var exceptionReport = {};
+                var exceptionCode = node.getAttribute('exceptionCode');
+                if (exceptionCode) {
+                    exceptionReport.exceptionCode = exceptionCode;
+                }
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    exceptionReport.exception = textNode.nodeValue;
+                }
+                return exceptionReport;
+            }
+        };
+        DirectGeocodeResponseReader.read = function (root) {
+            if (root.nodeName === 'XLS') {
+                var nsPrefix = root.prefix;
+                if (!nsPrefix) {
+                    nsPrefix = DirectGeocodeResponseReader.DEFAULTPREFIX;
+                }
+                var geocodeResponse = DirectGeocodeResponseReader.READERS[nsPrefix][root.nodeName](root);
+                return geocodeResponse;
+            } else if (root.nodeName === 'ExceptionReport') {
+                var exceptionReport = DirectGeocodeResponseReader.READERS[root.nodeName](root);
+                return exceptionReport;
+            } else {
+                var mess = MR.getMessage('SERVICE_RESPONSE_ANALYSE', root.nodeName);
+                throw new ErrSrv({
+                    message: mess,
+                    type: ErrSrv.TYPE_UNKERR,
+                    status: 200
+                });
+            }
+        };
+        function __getAttributes(node) {
+            if (node.attributes.length > 0) {
+                var nodeAttributes = {};
+                var attributes = node.attributes;
+                for (var i = 0; i < attributes.length; i++) {
+                    var attribute = attributes[i];
+                    nodeAttributes[attribute.nodeName] = attribute.nodeValue;
+                }
+                return nodeAttributes;
+            }
+        }
+        function __getChildNodes(node, data) {
+            if (node.hasChildNodes()) {
+                var children = node.childNodes;
+                var child;
+                var childName;
+                var childPrefix;
+                for (var i = 0; i < children.length; i++) {
+                    child = children[i];
+                    if (child.nodeType === 1) {
+                        childName = child.localName || child.baseName || child.nodeName;
+                        childPrefix = child.prefix || DirectGeocodeResponseReader.DEFAULTPREFIX;
+                        if (DirectGeocodeResponseReader.READERS[childPrefix][childName]) {
+                            var reader = DirectGeocodeResponseReader.READERS[childPrefix][childName];
+                            reader(child, data);
+                        } else {
+                            __getChildNodes(child, data);
+                        }
+                    }
+                }
+            }
+        }
+        function __getChildValue(node) {
+            var textNode;
+            var value = '';
+            if (node.hasChildNodes()) {
+                textNode = node.firstChild;
+                if (textNode.nodeType === 3) {
+                    value = textNode.nodeValue;
+                }
+            }
+            return value;
+        }
+        function __checkServiceAttributes(XLSNode) {
+            if (XLSNode.attributes.length > 0) {
+                var xlsAttributes = __getAttributes(XLSNode);
+                for (var att in xlsAttributes) {
+                    if (xlsAttributes.hasOwnProperty(att)) {
+                        if (att === 'version') {
+                            if (xlsAttributes['version'] !== DirectGeocodeResponseReader.VERSION) {
+                                console.log('[DirectGeocodeResponseReader] geocode version is not the expected one : there may be errors in parsing');
+                                return;
+                            }
+                        }
+                        if (att === 'xmlns') {
+                            if (xlsAttributes[att] !== DirectGeocodeResponseReader.NAMESPACES[DirectGeocodeResponseReader.DEFAULTPREFIX]) {
+                                console.log('[DirectGeocodeResponseReader] geocode response default namespace is not the expected one');
+                                return;
+                            }
+                            continue;
+                        }
+                        var prefix = att.split(':')[0];
+                        var ns = att.split(':')[1];
+                        if (prefix === 'xmlns' && ns) {
+                            if (DirectGeocodeResponseReader.NAMESPACES[ns]) {
+                                if (DirectGeocodeResponseReader.NAMESPACES[ns] !== xlsAttributes[att]) {
+                                    console.log('[DirectGeocodeResponseReader] geocode response ' + att + ' namespace is not the expected one');
+                                    return;
+                                }
+                            }
+                        }
+                        if (ns === 'schemaLocation') {
+                            if (DirectGeocodeResponseReader.SCHEMALOCATION !== xlsAttributes[att]) {
+                                console.log('[DirectGeocodeResponseReader] geocode response schema location is not the expected one');
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return DirectGeocodeResponseReader;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, ServicesGeocodeResponseModelGeocodeResponse, ServicesGeocodeResponseModelDirectGeocodedLocation);
+    ServicesGeocodeResponseDirectGeocodeResponseFactory = function (Logger, ErrorService, MRes, XML, DirectGeocodeResponseReader) {
+        var DirectGeocodeReponseFactory = {
+            build: function (options) {
+                var data = null;
+                if (options.response) {
+                    if (options.rawResponse) {
+                        data = options.response;
+                    } else {
+                        try {
+                            var p = new XML({ reader: DirectGeocodeResponseReader });
+                            if (typeof options.response === 'string') {
+                                p.setXMLString(options.response);
+                            } else {
+                                p.setXMLDoc(options.response);
+                            }
+                            data = p.parse();
+                            if (!data) {
+                                throw new Error('L\'analyse de la réponse du service !?');
+                            }
+                        } catch (e) {
+                            var message = e.message;
+                            if (typeof options.response === 'string') {
+                                message += '(\'' + options.response + '\')';
+                            } else {
+                                message += '(\'' + options.response.documentElement.innerHTML + '\')';
+                            }
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_ANALYSE', message),
+                                type: ErrorService.TYPE_UNKERR,
+                                status: -1
+                            }));
+                            return;
+                        }
+                        if (data.exceptionReport) {
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', data.exceptionReport),
+                                type: ErrorService.TYPE_SRVERR,
+                                status: 200
+                            }));
+                            return;
+                        }
+                    }
+                } else {
+                    options.onError.call(options.scope, new ErrorService({
+                        message: MRes.getMessage('SERVICE_RESPONSE_EMPTY'),
+                        type: ErrorService.TYPE_SRVERR,
+                        status: -1
+                    }));
+                    return;
+                }
+                options.onSuccess.call(options.scope, data);
+                return;
+            }
+        };
+        return DirectGeocodeReponseFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, UtilsMessagesResources, FormatsXML, ServicesGeocodeFormatsDirectGeocodeResponseReader);
+    ServicesGeocodeGeocode = function (Logger, _, ErrorService, CommonService, DirectGeocodeRequestFactory, DirectGeocodeResponseFactory) {
+        function Geocode(options) {
+            if (!(this instanceof Geocode)) {
+                throw new TypeError(_.getMessage('CLASS_CONSTRUCTOR', 'Geocode'));
+            }
+            this.CLASSNAME = 'Geocode';
+            CommonService.apply(this, arguments);
+            if (!options.location) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'location'));
+            }
+            if (typeof options.location === 'object' && Object.keys(options.location).length === 0) {
+                throw new Error(_.getMessage('PARAM_EMPTY', 'location'));
+            } else if (typeof options.location === 'string' && options.location.length === 0) {
+                throw new Error(_.getMessage('PARAM_EMPTY', 'location'));
+            }
+            this.options.location = options.location;
+            if (!options.filterOptions || typeof options.filterOptions !== 'object') {
+                this.options.filterOptions = options.filterOptions = { type: ['StreetAddress'] };
+            }
+            if (Object.keys(options.filterOptions).length === 0) {
+                this.options.filterOptions = { type: ['StreetAddress'] };
+            }
+            var filter = Object.keys(options.filterOptions);
+            for (var i = 0; i < filter.length; i++) {
+                var key = filter[i];
+                var filtersCouldBeNumberList = [
+                    'department',
+                    'number',
+                    'postalCode',
+                    'insee',
+                    'importance',
+                    'ID',
+                    'IDTR',
+                    'absorbedCity',
+                    'sheet',
+                    'section',
+                    'inseeRegion',
+                    'inseeDepartment'
+                ];
+                if (filtersCouldBeNumberList.indexOf(key) !== -1 && typeof options.filterOptions[key] !== 'string') {
+                    options.filterOptions[key] = options.filterOptions[key].toString();
+                }
+                if (!options.filterOptions[key]) {
+                    delete this.options.filterOptions[key];
+                }
+            }
+            this.options.filterOptions.type = options.filterOptions.type || ['StreetAddress'];
+            this.options.maximumResponses = options.maximumResponses || 25;
+            this.options.returnFreeForm = options.returnFreeForm || false;
+            this.options.srs = options.srs || 'EPSG:4326';
+            this.options.outputFormat = 'xml';
+        }
+        Geocode.prototype = Object.create(CommonService.prototype, {});
+        Geocode.prototype.constructor = Geocode;
+        Geocode.prototype.buildRequest = function (error, success) {
+            var options = {
+                httpMethod: this.options.httpMethod,
+                location: this.options.location,
+                returnFreeForm: this.options.returnFreeForm,
+                filterOptions: this.options.filterOptions,
+                srs: this.options.srs,
+                maximumResponses: this.options.maximumResponses
+            };
+            this.request = DirectGeocodeRequestFactory.build(options);
+            if (!this.request) {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_REQUEST_BUILD')));
+            } else {
+                success.call(this, this.request);
+            }
+        };
+        Geocode.prototype.analyzeResponse = function (error, success) {
+            if (this.response) {
+                var options = {
+                    response: this.response,
+                    rawResponse: this.options.rawResponse,
+                    onError: error,
+                    onSuccess: success,
+                    scope: this
+                };
+                DirectGeocodeResponseFactory.build(options);
+            } else {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_RESPONSE_EMPTY')));
+            }
+        };
+        return Geocode;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, ServicesCommonService, ServicesGeocodeRequestDirectGeocodeRequestFactory, ServicesGeocodeResponseDirectGeocodeResponseFactory);
+    ServicesGeocodeRequestReverseGeocodeRequestFactory = function (Logger, XLS, LocationUtilityService) {
+        var ReverseGeocodeRequestFactory = {
+            build: function (options) {
+                var settings = options || {};
+                var request = null;
+                var oLUS = new LocationUtilityService({
+                    position: settings.position,
+                    returnFreeForm: settings.returnFreeForm,
+                    filterOptions: settings.filterOptions
+                });
+                var oXLS = new XLS({
+                    srsName: settings.srs,
+                    maximumResponses: settings.maximumResponses
+                });
+                oXLS.namespace = true;
+                oXLS.setService(oLUS);
+                request = oXLS.build();
+                if (settings.httpMethod == 'GET') {
+                    var myRequest = 'qxml=' + encodeURIComponent(request).replace(/\-/g, '%2D').replace(/\_/g, '%5F').replace(/\./g, '%2E').replace(/\!/g, '%21').replace(/\~/g, '%7E').replace(/\*/g, '%2A').replace(/\'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
+                    request = myRequest;
+                }
+                return request;
+            }
+        };
+        return ReverseGeocodeRequestFactory;
+    }(UtilsLoggerByDefault, FormatsXLS, FormatsXLSLocationUtilityService);
+    ServicesGeocodeResponseModelReverseGeocodedLocation = function (GeocodedLocation) {
+        function ReverseGeocodedLocation() {
+            if (!(this instanceof ReverseGeocodedLocation)) {
+                throw new TypeError('ReverseGeocodedLocation constructor cannot be called as a function.');
+            }
+            GeocodedLocation.apply(this, arguments);
+            this.CLASSNAME = 'ReverseGeocodedLocation';
+            this.searchCenterDistance = null;
+        }
+        ReverseGeocodedLocation.prototype = Object.create(GeocodedLocation.prototype);
+        ReverseGeocodedLocation.prototype.constructor = ReverseGeocodedLocation;
+        return ReverseGeocodedLocation;
+    }(ServicesGeocodeResponseModelGeocodedLocation);
+    ServicesGeocodeFormatsReverseGeocodeResponseReader = function (Logger, MR, ErrSrv, ReverseGeocodeResponse, ReverseGeocodedLocation) {
+        var ReverseGeocodeResponseReader = {};
+        ReverseGeocodeResponseReader.VERSION = '1.2';
+        ReverseGeocodeResponseReader.NAMESPACES = {
+            xmlns: 'http://www.opengis.net/xls',
+            gml: 'http://www.opengis.net/gml',
+            xls: 'http://www.opengis.net/xls',
+            xlsext: 'http://www.opengis.net/xlsext',
+            xsi: 'http://www.w3.org/2001/XMLSchema-instance'
+        };
+        ReverseGeocodeResponseReader.SCHEMALOCATION = 'http://wxs.ign.fr/schemas/olsAll.xsd';
+        ReverseGeocodeResponseReader.DEFAULTPREFIX = 'xls';
+        ReverseGeocodeResponseReader.READERS = {
+            xls: {
+                XLS: function (root) {
+                    var reverseGeocodeResponse = new ReverseGeocodeResponse();
+                    __checkServiceAttributes(root);
+                    __getChildNodes(root, reverseGeocodeResponse);
+                    return reverseGeocodeResponse;
+                },
+                ReverseGeocodedLocation: function (node, reverseGeocodeResponse) {
+                    var reverseGeocodedLocation = new ReverseGeocodedLocation();
+                    __getChildNodes(node, reverseGeocodedLocation);
+                    if (reverseGeocodeResponse && Array.isArray(reverseGeocodeResponse.locations)) {
+                        reverseGeocodeResponse.locations.push(reverseGeocodedLocation);
+                    }
+                },
+                Address: function (node, reverseGeocodedLocation) {
+                    var countrycode = node.getAttribute('countryCode');
+                    if (reverseGeocodedLocation && countrycode) {
+                        reverseGeocodedLocation.type = countrycode;
+                    }
+                    __getChildNodes(node, reverseGeocodedLocation);
+                },
+                Building: function (node, reverseGeocodedLocation) {
+                    var num = node.getAttribute('number');
+                    if (reverseGeocodedLocation && reverseGeocodedLocation.hasOwnProperty('placeAttributes')) {
+                        if (num) {
+                            reverseGeocodedLocation.placeAttributes.number = num;
+                        } else if (node.getAttribute('buildingName')) {
+                            reverseGeocodedLocation.placeAttributes.number = node.getAttribute('buildingName');
+                        } else if (node.getAttribute('subdivision')) {
+                            reverseGeocodedLocation.placeAttributes.number = node.getAttribute('subdivision');
+                        }
+                    }
+                },
+                Street: function (node, reverseGeocodedLocation) {
+                    if (reverseGeocodedLocation.type === 'StreetAddress') {
+                        reverseGeocodedLocation.placeAttributes.street = __getChildValue(node);
+                    } else if (reverseGeocodedLocation.type === 'CadastralParcel') {
+                        reverseGeocodedLocation.placeAttributes.cadastralParcel = __getChildValue(node);
+                    }
+                },
+                Place: function (node, reverseGeocodedLocation) {
+                    var placeType = node.getAttribute('type');
+                    var placeName = __getChildValue(node);
+                    if (reverseGeocodedLocation && reverseGeocodedLocation.hasOwnProperty('placeAttributes')) {
+                        if (placeType === 'Municipality') {
+                            reverseGeocodedLocation.placeAttributes.municipality = placeName;
+                        } else if (placeType === 'Bbox') {
+                            var values = placeName.split(';');
+                            if (values.length === 4) {
+                                reverseGeocodedLocation.placeAttributes.bbox = {
+                                    left: parseFloat(values[0]),
+                                    right: parseFloat(values[2]),
+                                    top: parseFloat(values[1]),
+                                    bottom: parseFloat(values[3])
+                                };
+                            }
+                        } else if (placeType === 'Commune') {
+                            reverseGeocodedLocation.placeAttributes.commune = placeName;
+                        } else if (placeType === 'Departement') {
+                            reverseGeocodedLocation.placeAttributes.department = placeName;
+                        } else if (placeType === 'INSEE') {
+                            reverseGeocodedLocation.placeAttributes.insee = placeName;
+                        } else if (placeType === 'Qualite') {
+                            reverseGeocodedLocation.placeAttributes.quality = placeName;
+                        } else if (placeType === 'Territoire') {
+                            reverseGeocodedLocation.placeAttributes.territory = placeName;
+                        } else if (placeType === 'ID') {
+                            reverseGeocodedLocation.placeAttributes.ID = placeName;
+                        } else if (placeType === 'ID_TR') {
+                            reverseGeocodedLocation.placeAttributes.IDTR = placeName;
+                        } else if (placeType === 'Importance') {
+                            reverseGeocodedLocation.placeAttributes.importance = parseInt(placeName, 10);
+                        } else if (placeType === 'Nature') {
+                            reverseGeocodedLocation.placeAttributes.nature = placeName;
+                        } else if (placeType === 'Numero') {
+                            reverseGeocodedLocation.placeAttributes.number = placeName;
+                        } else if (placeType === 'Feuille') {
+                            reverseGeocodedLocation.placeAttributes.sheet = placeName;
+                        } else if (placeType === 'Section') {
+                            reverseGeocodedLocation.placeAttributes.section = placeName;
+                        } else if (placeType === 'CommuneAbsorbee') {
+                            reverseGeocodedLocation.placeAttributes.absorbedCity = placeName;
+                        } else if (placeType === 'Arrondissement') {
+                            if (placeName) {
+                                reverseGeocodedLocation.placeAttributes.arrondissement = placeName;
+                            }
+                        } else if (placeType === 'Type') {
+                            reverseGeocodedLocation.placeAttributes.origin = placeName;
+                        } else if (placeType === 'Prefecture') {
+                            reverseGeocodedLocation.placeAttributes.prefecture = placeName;
+                        } else if (placeType === 'InseeRegion') {
+                            reverseGeocodedLocation.placeAttributes.inseeRegion = placeName;
+                        } else if (placeType === 'InseeDepartment') {
+                            reverseGeocodedLocation.placeAttributes.inseeDepartment = placeName;
+                        }
+                    }
+                },
+                PostalCode: function (node, reverseGeocodedLocation) {
+                    if (reverseGeocodedLocation && reverseGeocodedLocation.hasOwnProperty('placeAttributes')) {
+                        reverseGeocodedLocation.placeAttributes.postalCode = __getChildValue(node);
+                    }
+                },
+                SearchCentreDistance: function (node, reverseGeocodedLocation) {
+                    if (reverseGeocodedLocation) {
+                        reverseGeocodedLocation.searchCenterDistance = parseFloat(node.getAttribute('value'));
+                    }
+                },
+                Error: function (node) {
+                    var srvMess = node.getAttribute('message');
+                    var errorCode = node.getAttribute('errorCode');
+                    var message = MR.getMessage('SERVICE_RESPONSE_EXCEPTION', '(' + errorCode + ') : ' + srvMess);
+                    throw new ErrSrv({
+                        message: message,
+                        type: ErrSrv.TYPE_SRVERR
+                    });
+                }
+            },
+            gml: {
+                pos: function (node, reverseGeocodedLocation) {
+                    var pos = __getChildValue(node);
+                    if (reverseGeocodedLocation && pos) {
+                        reverseGeocodedLocation.position = {
+                            x: parseFloat(pos.split(' ')[0]),
+                            y: parseFloat(pos.split(' ')[1])
+                        };
+                    }
+                }
+            },
+            xlsext: {
+                ExtendedGeocodeMatchCode: function (node, reverseGeocodedLocation) {
+                    if (reverseGeocodedLocation) {
+                        reverseGeocodedLocation.matchType = __getChildValue(node);
+                    }
+                }
+            },
+            ExceptionReport: function (node) {
+                var response = {};
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (child.nodeName === 'Exception') {
+                            response.exceptionReport = ReverseGeocodeResponseReader.READERS['Exception'](child);
+                        }
+                    }
+                }
+                return response;
+            },
+            Exception: function (node) {
+                var exceptionReport = {};
+                var exceptionCode = node.getAttribute('exceptionCode');
+                if (exceptionCode) {
+                    exceptionReport.exceptionCode = exceptionCode;
+                }
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    exceptionReport.exception = textNode.nodeValue;
+                }
+                return exceptionReport;
+            }
+        };
+        ReverseGeocodeResponseReader.read = function (root) {
+            if (root.nodeName === 'XLS') {
+                var nsPrefix = root.prefix;
+                if (!nsPrefix) {
+                    nsPrefix = ReverseGeocodeResponseReader.DEFAULTPREFIX;
+                }
+                var geocodeResponse = ReverseGeocodeResponseReader.READERS[nsPrefix][root.nodeName](root);
+                return geocodeResponse;
+            } else if (root.nodeName === 'ExceptionReport') {
+                var exceptionReport = ReverseGeocodeResponseReader.READERS[root.nodeName](root);
+                return exceptionReport;
+            } else {
+                throw new Error('Erreur lors de la lecture de la réponse : elle n\'est pas au format attendu.');
+            }
+        };
+        function __getAttributes(node) {
+            if (node.attributes.length > 0) {
+                var nodeAttributes = {};
+                var attributes = node.attributes;
+                for (var i = 0; i < attributes.length; i++) {
+                    var attribute = attributes[i];
+                    nodeAttributes[attribute.nodeName] = attribute.nodeValue;
+                }
+                return nodeAttributes;
+            }
+        }
+        function __getChildNodes(node, data) {
+            if (node.hasChildNodes()) {
+                var children = node.childNodes;
+                var child;
+                var childName;
+                var childPrefix;
+                for (var i = 0; i < children.length; i++) {
+                    child = children[i];
+                    if (child.nodeType === 1) {
+                        childName = child.localName || child.baseName || child.nodeName;
+                        childPrefix = child.prefix || ReverseGeocodeResponseReader.DEFAULTPREFIX;
+                        if (ReverseGeocodeResponseReader.READERS[childPrefix][childName]) {
+                            var reader = ReverseGeocodeResponseReader.READERS[childPrefix][childName];
+                            reader(child, data);
+                        } else {
+                            __getChildNodes(child, data);
+                        }
+                    }
+                }
+            }
+        }
+        function __getChildValue(node) {
+            var textNode;
+            var value = '';
+            if (node.hasChildNodes()) {
+                textNode = node.firstChild;
+                if (textNode.nodeType === 3) {
+                    value = textNode.nodeValue;
+                }
+            }
+            return value;
+        }
+        function __checkServiceAttributes(XLSNode) {
+            if (XLSNode.attributes.length > 0) {
+                var xlsAttributes = __getAttributes(XLSNode);
+                for (var att in xlsAttributes) {
+                    if (xlsAttributes.hasOwnProperty(att)) {
+                        if (att === 'version') {
+                            if (xlsAttributes['version'] !== ReverseGeocodeResponseReader.VERSION) {
+                                console.log('[ReverseGeocodeResponseReader] geocode version is not the expected one : there may be errors in parsing');
+                                return;
+                            }
+                        }
+                        if (att === 'xmlns') {
+                            if (xlsAttributes[att] !== ReverseGeocodeResponseReader.NAMESPACES[ReverseGeocodeResponseReader.DEFAULTPREFIX]) {
+                                console.log('[ReverseGeocodeResponseReader] geocode response default namespace is not the expected one');
+                                return;
+                            }
+                            continue;
+                        }
+                        var prefix = att.split(':')[0];
+                        var ns = att.split(':')[1];
+                        if (prefix === 'xmlns' && ns) {
+                            if (ReverseGeocodeResponseReader.NAMESPACES[ns]) {
+                                if (ReverseGeocodeResponseReader.NAMESPACES[ns] !== xlsAttributes[att]) {
+                                    console.log('[ReverseGeocodeResponseReader] geocode response ' + att + ' namespace is not the expected one');
+                                    return;
+                                }
+                            }
+                        }
+                        if (ns === 'schemaLocation') {
+                            if (ReverseGeocodeResponseReader.SCHEMALOCATION !== xlsAttributes[att]) {
+                                console.log('[ReverseGeocodeResponseReader] geocode response schema location is not the expected one');
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return ReverseGeocodeResponseReader;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, ServicesGeocodeResponseModelGeocodeResponse, ServicesGeocodeResponseModelReverseGeocodedLocation);
+    ServicesGeocodeResponseReverseGeocodeResponseFactory = function (Logger, MRes, ErrorService, XML, ReverseGeocodeResponseReader) {
+        var ReverseGeocodeReponseFactory = {
+            build: function (options) {
+                var data = null;
+                if (options.response) {
+                    if (options.rawResponse) {
+                        data = options.response;
+                    } else {
+                        try {
+                            var p = new XML({ reader: ReverseGeocodeResponseReader });
+                            if (typeof options.response === 'string') {
+                                p.setXMLString(options.response);
+                            } else {
+                                p.setXMLDoc(options.response);
+                            }
+                            data = p.parse();
+                            if (!data) {
+                                throw new Error('L\'analyse de la réponse du service !?');
+                            }
+                        } catch (e) {
+                            e.status = 200;
+                            options.onError.call(options.scope, e);
+                            return;
+                        }
+                        if (data.exceptionReport) {
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', data.exceptionReport),
+                                type: ErrorService.TYPE_SRVERR,
+                                status: 200
+                            }));
+                            return;
+                        }
+                        if (options.scope && options.scope.options && options.scope.options.srs && options.scope.options.srs !== 'EPSG:4326') {
+                            var location;
+                            var pos;
+                            if (data || data.locations || data.locations.length) {
+                                for (var i = 0; i < data.locations.length; i++) {
+                                    location = data.locations[i];
+                                    if (location) {
+                                        pos = location.position;
+                                        if (pos) {
+                                            location.position = {
+                                                x: pos.y,
+                                                y: pos.x
+                                            };
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    options.onError.call(options.scope, new ErrorService({
+                        message: MRes.getMessage('SERVICE_RESPONSE_EMPTY'),
+                        type: ErrorService.TYPE_SRVERR,
+                        status: -1
+                    }));
+                    return;
+                }
+                options.onSuccess.call(options.scope, data);
+                return;
+            }
+        };
+        return ReverseGeocodeReponseFactory;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, FormatsXML, ServicesGeocodeFormatsReverseGeocodeResponseReader);
+    ServicesGeocodeReverseGeocode = function (Logger, _, ErrorService, CommonService, ReverseGeocodeRequestFactory, ReverseGeocodeResponseFactory) {
+        function ReverseGeocode(options) {
+            if (!(this instanceof ReverseGeocode)) {
+                throw new TypeError(_.getMessage('CLASS_CONSTRUCTOR', 'ReverseGeocode'));
+            }
+            this.CLASSNAME = 'ReverseGeocode';
+            CommonService.apply(this, arguments);
+            if (!options.position) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'position'));
+            }
+            if (options.position.x == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'position.x'));
+            }
+            if (options.position.y == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'position.y'));
+            }
+            this.options.position = options.position;
+            if (!options.filterOptions || typeof options.filterOptions !== 'object') {
+                this.options.filterOptions = options.filterOptions = { type: ['StreetAddress'] };
+            }
+            if (Object.keys(options.filterOptions).length === 0) {
+                this.options.filterOptions = { type: ['StreetAddress'] };
+            }
+            var filter = Object.keys(options.filterOptions);
+            for (var i = 0; i < filter.length; i++) {
+                var key = filter[i];
+                if (!options.filterOptions[key] || Object.keys(options.filterOptions[key]).length === 0) {
+                    delete this.options.filterOptions[key];
+                }
+            }
+            this.options.filterOptions.type = options.filterOptions.type || ['StreetAddress'];
+            if (!Array.isArray(this.options.filterOptions.type)) {
+                throw new Error(_.getMessage('PARAM_TYPE', 'filterOptions.type'));
+            }
+            this.options.maximumResponses = options.maximumResponses || 25;
+            this.options.returnFreeForm = options.returnFreeForm || false;
+            this.options.srs = options.srs || 'CRS:84';
+            if (ReverseGeocode.geoEPSG.indexOf(this.options.srs) === -1) {
+                this.options.position = {
+                    x: this.options.position.y,
+                    y: this.options.position.x
+                };
+                if (this.options.filterOptions && this.options.filterOptions.circle) {
+                    var circle = this.options.filterOptions.circle;
+                    this.options.filterOptions.circle = {
+                        x: circle.y,
+                        y: circle.x,
+                        radius: circle.radius
+                    };
+                }
+                if (this.options.filterOptions && this.options.filterOptions.polygon) {
+                    var polygon = this.options.filterOptions.polygon;
+                    for (i = 0; i < polygon.length; i++) {
+                        var coords = polygon[i];
+                        this.options.filterOptions.polygon[i] = {
+                            x: coords.y,
+                            y: coords.x
+                        };
+                    }
+                }
+            }
+            this.options.outputFormat = 'xml';
+        }
+        ReverseGeocode.prototype = Object.create(CommonService.prototype, {});
+        ReverseGeocode.prototype.constructor = ReverseGeocode;
+        ReverseGeocode.prototype.buildRequest = function (error, success) {
+            var options = {
+                httpMethod: this.options.httpMethod,
+                position: this.options.position,
+                returnFreeForm: this.options.returnFreeForm,
+                filterOptions: this.options.filterOptions,
+                srs: 'EPSG:4326',
+                maximumResponses: this.options.maximumResponses
+            };
+            this.request = ReverseGeocodeRequestFactory.build(options);
+            if (!this.request) {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_REQUEST_BUILD')));
+            } else {
+                success.call(this, this.request);
+            }
+        };
+        ReverseGeocode.prototype.analyzeResponse = function (error, success) {
+            if (this.response) {
+                var options = {
+                    response: this.response,
+                    rawResponse: this.options.rawResponse,
+                    onError: error,
+                    onSuccess: success,
+                    scope: this
+                };
+                ReverseGeocodeResponseFactory.build(options);
+            } else {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_RESPONSE_EMPTY')));
+            }
+        };
+        ReverseGeocode.geoEPSG = ['EPSG:4326'];
+        return ReverseGeocode;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, ServicesCommonService, ServicesGeocodeRequestReverseGeocodeRequestFactory, ServicesGeocodeResponseReverseGeocodeResponseFactory);
+    ServicesAutoCompleteResponseModelAutoCompleteResponse = function () {
+        function AutoCompleteResponse() {
+            if (!(this instanceof AutoCompleteResponse)) {
+                throw new TypeError('AutoCompleteResponse constructor cannot be called as a function.');
+            }
+            this.suggestedLocations = [];
+        }
+        AutoCompleteResponse.prototype = { constructor: AutoCompleteResponse };
+        return AutoCompleteResponse;
+    }();
+    ServicesAutoCompleteResponseModelSuggestedLocation = function () {
+        function SuggestedLocation() {
+            if (!(this instanceof SuggestedLocation)) {
+                throw new TypeError('SuggestedLocation constructor cannot be called as a function.');
+            }
+            this.type = null;
+            this.position = {
+                x: null,
+                y: null
+            };
+            this.commune = null;
+            this.fullText = null;
+            this.postalCode = null;
+            this.classification = null;
+            this.street = null;
+            this.poi = null;
+            this.kind = null;
+        }
+        SuggestedLocation.prototype = { constructor: SuggestedLocation };
+        return SuggestedLocation;
+    }();
+    ServicesAutoCompleteResponseAutoCompleteResponseFactory = function (Logger, ErrorService, MRes, XML, AutoCompleteResponse, SuggestedLocation) {
+        var AutoCompleteResponseFactory = {
+            build: function (options) {
+                var data = null;
+                if (options.response) {
+                    if (options.rawResponse) {
+                        data = options.response;
+                    } else {
+                        var JSONResponse;
+                        if (typeof options.response === 'string') {
+                            JSONResponse = window.JSON.parse(options.response);
+                        } else {
+                            JSONResponse = options.response;
+                        }
+                        if (JSONResponse) {
+                            if (JSONResponse.error) {
+                                options.onError.call(options.scope, new ErrorService({
+                                    message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', JSONResponse.error.description),
+                                    status: JSONResponse.error.code,
+                                    type: ErrorService.TYPE_SRVERR
+                                }));
+                                return;
+                            }
+                            data = new AutoCompleteResponse();
+                            if (JSONResponse.results && Array.isArray(JSONResponse.results)) {
+                                var suggestedLocation;
+                                for (var i = 0; i < JSONResponse.results.length; i++) {
+                                    var result = JSONResponse.results[i];
+                                    suggestedLocation = new SuggestedLocation();
+                                    if (suggestedLocation) {
+                                        if (result && result.country === 'StreetAddress') {
+                                            suggestedLocation.street = result.street;
+                                            suggestedLocation.type = 'StreetAddress';
+                                        } else if (result && result.country === 'PositionOfInterest') {
+                                            suggestedLocation.poi = result.street;
+                                            suggestedLocation.kind = result.kind;
+                                            suggestedLocation.type = 'PositionOfInterest';
+                                        }
+                                        if (suggestedLocation.position) {
+                                            suggestedLocation.position.x = result.x;
+                                            suggestedLocation.position.y = result.y;
+                                        }
+                                        suggestedLocation.commune = result.city;
+                                        suggestedLocation.fullText = result.fulltext;
+                                        suggestedLocation.postalCode = result.zipcode;
+                                        suggestedLocation.classification = result.classification;
+                                    }
+                                    data.suggestedLocations.push(suggestedLocation);
+                                }
+                            } else {
+                                options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_FORMAT_3')));
+                                return;
+                            }
+                            if (!data.suggestedLocations.length) {
+                                options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_FORMAT_3')));
+                                return;
+                            }
+                        }
+                        if (!data) {
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_ANALYSE_2'),
+                                type: ErrorService.TYPE_UNKERR,
+                                status: -1
+                            }));
+                            return;
+                        }
+                        if (data.exceptionReport) {
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', data.exceptionReport),
+                                type: ErrorService.TYPE_SRVERR,
+                                status: 200
+                            }));
+                            return;
+                        }
+                    }
+                } else {
+                    options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EMPTY')));
+                    return;
+                }
+                options.onSuccess.call(options.scope, data);
+                return;
+            }
+        };
+        return AutoCompleteResponseFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, UtilsMessagesResources, FormatsXML, ServicesAutoCompleteResponseModelAutoCompleteResponse, ServicesAutoCompleteResponseModelSuggestedLocation);
+    ServicesAutoCompleteAutoComplete = function (CommonService, AutoCompleteResponseFactory, Logger, MR, ErrorService, Helper) {
+        function AutoComplete(options) {
+            if (!(this instanceof AutoComplete)) {
+                throw new TypeError(MR.getMessage('CLASS_CONSTRUCTOR', 'AutoComplete'));
+            }
+            this.CLASSNAME = 'AutoComplete';
+            CommonService.apply(this, arguments);
+            if (!options.text) {
+                throw new Error(MR.getMessage('PARAM_MISSING', 'text'));
+            }
+            this.options.text = options.text;
+            if (!options.filterOptions || typeof options.filterOptions !== 'object') {
+                this.options.filterOptions = options.filterOptions = {
+                    territory: [],
+                    type: ['StreetAddress']
+                };
+            }
+            if (Object.keys(options.filterOptions).length === 0) {
+                this.options.filterOptions = {
+                    territory: [],
+                    type: ['StreetAddress']
+                };
+            }
+            this.options.filterOptions.type = options.filterOptions.type || ['StreetAddress'];
+            this.options.filterOptions.territory = options.filterOptions.territory || [];
+            this.options.maximumResponses = options.maximumResponses || 10;
+            if (this.options.protocol === 'XHR' && this.options.httpMethod === 'POST') {
+                this.options.httpMethod = 'GET';
+            }
+            this.options.outputFormat = 'json';
+        }
+        AutoComplete.prototype = Object.create(CommonService.prototype, {});
+        AutoComplete.prototype.constructor = AutoComplete;
+        AutoComplete.prototype.buildRequest = function (error, success) {
+            var territories = '';
+            if (this.options.filterOptions.territory) {
+                territories = this.options.filterOptions.territory.join(';');
+            }
+            var types = '';
+            if (this.options.filterOptions.type) {
+                types = this.options.filterOptions.type.join(',');
+            }
+            this.request = Helper.normalyzeParameters({
+                text: encodeURIComponent(this.options.text),
+                type: types,
+                terr: territories,
+                maximumResponses: this.options.maximumResponses
+            });
+            success.call(this, this.request);
+        };
+        AutoComplete.prototype.analyzeResponse = function (error, success) {
+            if (this.response) {
+                var options = {
+                    response: this.response,
+                    rawResponse: this.options.rawResponse,
+                    onSuccess: success,
+                    onError: error,
+                    scope: this
+                };
+                AutoCompleteResponseFactory.build(options);
+            } else {
+                error.call(this, new ErrorService(MR.getMessage('SERVICE_RESPONSE_EMPTY')));
+            }
+        };
+        return AutoComplete;
+    }(ServicesCommonService, ServicesAutoCompleteResponseAutoCompleteResponseFactory, UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, UtilsHelper);
+    FormatsXLSRouteServiceModelRoutePlan = function (Logger) {
+        function RoutePlan(options) {
+            if (!(this instanceof RoutePlan)) {
+                throw new TypeError('RoutePlan constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            if (!options.startPoint) {
+                throw new Error('l\'option \'startPoint\' n\'est pas renseignée !');
+            }
+            if (!options.endPoint) {
+                throw new Error('l\'option \'endPoint\' n\'est pas renseignée !');
+            }
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+        }
+        RoutePlan.prototype = {
+            constructor: RoutePlan,
+            requestString: null,
+            template: {
+                routePlan: '<RoutePlan>' + '__ROUTEPREFERENCE__' + '__GRAPH__' + '__WAYPOINTLIST__' + '__AVOIDLIST__' + '</RoutePlan>',
+                routePreference: '<RoutePreference>__VALUEROUTEPREFERENCE__</RoutePreference>',
+                graph: '<xlsext:graphName xmlns:xlsext="http://www.opengis.net/xlsext" name="__VALUEGRAPH__"/>',
+                wayPointList: {
+                    container: '<WayPointList>' + '__STARTPOINT__' + '__VIAPOINT__' + '__ENDPOINT__' + '</WayPointList>',
+                    point: '<Position><gml:Point xmlns:gml="http://www.opengis.net/gml"><gml:pos>__X__ __Y__</gml:pos></gml:Point></Position>',
+                    startPoint: '<StartPoint>' + '__POINT__' + '</StartPoint>',
+                    endPoint: '<EndPoint>' + '__POINT__' + '</EndPoint>',
+                    viaPoint: '<ViaPoint>' + '__POINT__' + '</ViaPoint>'
+                },
+                avoidList: {
+                    container: '<AvoidList>' + '__AVOIDFEATURE__' + '</AvoidList>',
+                    avoidFeature: '<AvoidFeature>__VALUEAVOIDFEATURE__</AvoidFeature>'
+                }
+            },
+            toString: function () {
+                var template = '';
+                template = this.template.routePlan;
+                if (this.options.routePreference) {
+                    var tmplPreference = this.template.routePreference;
+                    tmplPreference = tmplPreference.replace(/__VALUEROUTEPREFERENCE__/, this.options.routePreference);
+                    template = template.replace(/__ROUTEPREFERENCE__/g, tmplPreference);
+                }
+                template = template.replace(/__ROUTEPREFERENCE__/g, '');
+                if (this.options.avoidFeature) {
+                    var tmplAvoidList = this.template.avoidList.container;
+                    var avoidFeatures = [];
+                    for (var i = 0; i < this.options.avoidFeature.length; i++) {
+                        var tmplAvoidFeature = this.template.avoidList.avoidFeature;
+                        tmplAvoidFeature = tmplAvoidFeature.replace(/__VALUEAVOIDFEATURE__/, this.options.avoidFeature[i]);
+                        avoidFeatures.push(tmplAvoidFeature);
+                    }
+                    tmplAvoidList = tmplAvoidList.replace(/__AVOIDFEATURE__/, avoidFeatures.join('\n'));
+                    template = template.replace(/__AVOIDLIST__/g, tmplAvoidList);
+                }
+                template = template.replace(/__AVOIDLIST__/g, '');
+                if (this.options.graph) {
+                    var tmplVehicle = this.template.graph;
+                    tmplVehicle = tmplVehicle.replace(/__VALUEGRAPH__/, this.options.graph);
+                    template = template.replace(/__GRAPH__/g, tmplVehicle);
+                }
+                template = template.replace(/__GRAPH__/g, '');
+                var tmplWayPointList = this.template.wayPointList.container;
+                var tmplPoint = '';
+                tmplPoint = this.template.wayPointList.point;
+                tmplPoint = tmplPoint.replace(/__X__/, this.options.startPoint.x);
+                tmplPoint = tmplPoint.replace(/__Y__/, this.options.startPoint.y);
+                tmplWayPointList = tmplWayPointList.replace(/__STARTPOINT__/, this.template.wayPointList.startPoint.replace(/__POINT__/, tmplPoint));
+                tmplPoint = this.template.wayPointList.point;
+                tmplPoint = tmplPoint.replace(/__X__/, this.options.endPoint.x);
+                tmplPoint = tmplPoint.replace(/__Y__/, this.options.endPoint.y);
+                tmplWayPointList = tmplWayPointList.replace(/__ENDPOINT__/, this.template.wayPointList.endPoint.replace(/__POINT__/, tmplPoint));
+                if (this.options.viaPoint) {
+                    var points = [];
+                    for (var j = 0; j < this.options.viaPoint.length; j++) {
+                        var p = this.options.viaPoint[j];
+                        tmplPoint = this.template.wayPointList.point;
+                        tmplPoint = tmplPoint.replace(/__X__/, p.x);
+                        tmplPoint = tmplPoint.replace(/__Y__/, p.y);
+                        points.push(tmplPoint);
+                    }
+                    tmplWayPointList = tmplWayPointList.replace(/__VIAPOINT__/, this.template.wayPointList.viaPoint.replace(/__POINT__/, points.join('\n')));
+                } else {
+                    tmplWayPointList = tmplWayPointList.replace(/__VIAPOINT__/, '');
+                }
+                template = template.replace(/__WAYPOINTLIST__/g, tmplWayPointList);
+                this.requestString = template;
+                return this.requestString;
+            }
+        };
+        return RoutePlan;
+    }(UtilsLoggerByDefault);
+    FormatsXLSRouteServiceDetermineRouteRequest = function (Logger, RoutePlan) {
+        function DetermineRouteRequest(options) {
+            if (!(this instanceof DetermineRouteRequest)) {
+                throw new TypeError('DetermineRouteRequest constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            for (var opt in options) {
+                if (options.hasOwnProperty(opt)) {
+                    this.options[opt] = options[opt];
+                }
+            }
+            this.CLASSNAME = 'DetermineRouteRequest';
+        }
+        DetermineRouteRequest.prototype = {
+            strRequest: null,
+            oRoutePlan: null,
+            template: {
+                determineRouteRequest: '<DetermineRouteRequest distanceUnit="__DISTANCEUNIT__">' + '__ROUTEPLAN__' + '__ROUTEINSTRUCTIONREQUEST__' + '__ROUTEGEOMETRYREQUEST__' + '__ROUTEMAPREQUEST__' + '</DetermineRouteRequest>',
+                routeInstructionRequest: '<RouteInstructionsRequest ' + 'provideGeometry="__PROVIDEGEOMETRY__" ' + 'provideBoundingBox="__PROVIDEBBOX__" />',
+                routeGeometryRequest: '<RouteGeometryRequest />',
+                routeMapRequest: ''
+            },
+            addRoute: function (oRoutePlan) {
+                if (oRoutePlan instanceof RoutePlan) {
+                    this.oRoutePlan = oRoutePlan;
+                }
+            },
+            constructor: DetermineRouteRequest,
+            toString: function () {
+                var template = '';
+                template = this.template.determineRouteRequest;
+                template = template.replace(/__DISTANCEUNIT__/g, this.options.distanceUnit || 'KM');
+                if (!this.oRoutePlan) {
+                    var settings = this.options.route;
+                    this.oRoutePlan = new RoutePlan(settings);
+                    if (!this.oRoutePlan) {
+                        throw new Error('La construction du calcul d\'initineraire n\'est pas correctement definie !?');
+                    }
+                }
+                template = template.replace(/__ROUTEPLAN__/g, this.oRoutePlan.toString());
+                var tmplInstruction = this.template.routeInstructionRequest;
+                tmplInstruction = tmplInstruction.replace(/__PROVIDEGEOMETRY__/g, this.options.provideGeometry || false);
+                tmplInstruction = tmplInstruction.replace(/__PROVIDEBBOX__/g, this.options.provideBoundingBox || false);
+                template = template.replace(/__ROUTEINSTRUCTIONREQUEST__/g, tmplInstruction);
+                var tmplGeometry = this.template.routeGeometryRequest;
+                template = template.replace(/__ROUTEGEOMETRYREQUEST__/g, tmplGeometry);
+                var tmplMap = this.template.routeMapRequest;
+                template = template.replace(/__ROUTEMAPREQUEST__/g, tmplMap);
+                this.strRequest = template;
+                return this.strRequest;
+            }
+        };
+        return DetermineRouteRequest;
+    }(UtilsLoggerByDefault, FormatsXLSRouteServiceModelRoutePlan);
+    FormatsXLSRouteServiceRouteRequestExtension = undefined;
+    FormatsXLSRouteService = function (Logger, AbstractService, DetermineRouteRequest, RouteRequestExtension) {
+        function RouteService(options) {
+            if (!(this instanceof RouteService)) {
+                throw new TypeError('RouteService constructor cannot be called as a function.');
+            }
+            this.CLASSNAME = 'RouteService';
+            this.CLASSTYPE = 'RouteRequest';
+            AbstractService.apply(this, arguments);
+        }
+        RouteService.prototype = Object.create(AbstractService.prototype, {});
+        RouteService.prototype.constructor = RouteService;
+        RouteService.prototype.addRequest = function (oRequest) {
+            if (oRequest.CLASSNAME === 'DetermineRouteRequest') {
+                this.oRequest = oRequest;
+            } else {
+                throw new Error('Ce n\'est pas un objet de type \'Route Request\' !?');
+            }
+        };
+        RouteService.prototype.addFilter = function (oFilter) {
+            if (oFilter instanceof RouteRequestExtension) {
+                this.oFilter = oFilter;
+            }
+        };
+        RouteService.prototype.toString = function () {
+            if (!this.oRequest) {
+                if (!this.options) {
+                    throw new Error('Les options ne sont pas renseignées, impossible de construire la requête !');
+                }
+                if (this.CLASSTYPE === 'RouteRequest') {
+                    var settings = {
+                        distanceUnit: this.options.distanceUnit || null,
+                        provideGeometry: this.options.provideGeometry || null,
+                        provideBoundingBox: this.options.provideBoundingBox || null,
+                        route: {
+                            routePreference: this.options.routePreference || null,
+                            startPoint: this.options.startPoint,
+                            viaPoint: this.options.viaPoint || null,
+                            endPoint: this.options.endPoint,
+                            avoidFeature: this.options.avoidFeature || null,
+                            graph: this.options.graph || null,
+                            expectedStartTime: this.options.expectedStartTime || null
+                        }
+                    };
+                    this.oRequest = new DetermineRouteRequest(settings);
+                    if (this.oFilter) {
+                        this.oRequest.addFilter(this.oFilter);
+                    }
+                }
+            }
+            if (!this.oRequest) {
+                throw new Error('Type de requête indefini !');
+            }
+            this.strRequest = this.oRequest.toString();
+            return this.strRequest;
+        };
+        return RouteService;
+    }(UtilsLoggerByDefault, FormatsXLSAbstractService, FormatsXLSRouteServiceDetermineRouteRequest, FormatsXLSRouteServiceRouteRequestExtension);
+    ServicesRouteRequestRouteRequestOLS = function (Logger, XLS, RouteService) {
+        var RouteRequestOLS = {
+            build: function (options) {
+                var request = null;
+                var settings = {
+                    startPoint: options.startPoint,
+                    endPoint: options.endPoint,
+                    viaPoint: options.viaPoints,
+                    provideBoundingBox: options.provideBbox,
+                    avoidFeature: options.exclusions,
+                    expectedStartTime: options.expectedStartTime,
+                    distanceUnit: options.distanceUnit,
+                    graph: options.graph,
+                    provideGeometry: options.geometryInInstructions,
+                    routePreference: options.routePreference
+                };
+                var oRS = new RouteService(settings);
+                var oXLS = new XLS({
+                    srsName: options.srs,
+                    maximumResponses: options.maximumResponses
+                });
+                oXLS.namespace = true;
+                oXLS.setService(oRS);
+                request = oXLS.build();
+                if (options.httpMethod == 'GET') {
+                    var myRequest = 'qxml=' + encodeURIComponent(request).replace(/\-/g, '%2D').replace(/\_/g, '%5F').replace(/\./g, '%2E').replace(/\!/g, '%21').replace(/\~/g, '%7E').replace(/\*/g, '%2A').replace(/\'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
+                    request = myRequest;
+                }
+                return request;
+            }
+        };
+        return RouteRequestOLS;
+    }(UtilsLoggerByDefault, FormatsXLS, FormatsXLSRouteService);
+    ServicesRouteRequestModelRouteParamREST = function (Logger) {
+        function RouteParamREST(options) {
+            if (!(this instanceof RouteParamREST)) {
+                throw new TypeError('RouteParamREST constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            this.origin = this.options.startPoint.x + ',' + this.options.startPoint.y;
+            this.destination = this.options.endPoint.x + ',' + this.options.endPoint.y;
+            this.waypoints = this.options.viaPoints || null;
+            this.startDateTime = this.options.expectedStartTime || null;
+            this.graphName = this.options.graph;
+            this.srs = this.options.srs;
+            this.exclusions = this.options.exclusions;
+            this.method = 'TIME';
+            if (this.options.routePreference) {
+                var value = this.options.routePreference;
+                switch (value) {
+                case 'fastest':
+                    this.method = 'TIME';
+                    break;
+                case 'shortest':
+                    this.method = 'DISTANCE';
+                    break;
+                default:
+                    this.method = 'TIME';
+                }
+            }
+            this.format = this.options.geometryInInstructions ? 'STANDARDEXT' : 'STANDARD';
+            this.tolerance = 10;
+            this.profileId = null;
+            this.profileName = null;
+        }
+        RouteParamREST.CLASSNAME = 'RouteParamREST';
+        RouteParamREST.prototype = {
+            constructor: RouteParamREST,
+            getWaypoints: function () {
+                if (!this.waypoints) {
+                    return;
+                }
+                var array = [];
+                for (var i = 0; i < this.waypoints.length; i++) {
+                    var obj = this.waypoints[i];
+                    array.push(obj.x + ',' + obj.y);
+                }
+                return array.join(';');
+            },
+            getExclusions: function () {
+                return this.exclusions.join(';');
+            }
+        };
+        RouteParamREST.prototype.getParams = function () {
+            var map = [];
+            map.push({
+                k: 'origin',
+                v: this.origin
+            });
+            map.push({
+                k: 'destination',
+                v: this.destination
+            });
+            map.push({
+                k: 'method',
+                v: this.method
+            });
+            if (this.waypoints) {
+                map.push({
+                    k: 'waypoints',
+                    v: this.getWaypoints()
+                });
+            }
+            if (this.startDateTime) {
+                map.push({
+                    k: 'startDateTime',
+                    v: this.startDateTime
+                });
+            }
+            if (this.graphName) {
+                map.push({
+                    k: 'graphName',
+                    v: this.graphName
+                });
+            }
+            if (this.exclusions) {
+                map.push({
+                    k: 'exclusions',
+                    v: this.getExclusions()
+                });
+            }
+            if (this.srs) {
+                map.push({
+                    k: 'srs',
+                    v: this.srs
+                });
+            }
+            if (this.format) {
+                map.push({
+                    k: 'format',
+                    v: this.format
+                });
+            }
+            return map;
+        };
+        return RouteParamREST;
+    }(UtilsLoggerByDefault);
+    ServicesRouteRequestRouteRequestREST = function (Logger, _, RouteParamREST) {
+        function RouteRequestREST(options) {
+            if (!(this instanceof RouteRequestREST)) {
+                throw new TypeError('RouteRequestREST constructor cannot be called as a function.');
+            }
+            if (!options) {
+                throw new Error(_.getMessage('PARAM_EMPTY', 'options'));
+            }
+            this.settings = options;
+        }
+        RouteRequestREST.prototype = {
+            requestString: null,
+            constructor: RouteRequestREST,
+            processRequestString: function () {
+                var oParams = new RouteParamREST(this.settings);
+                var params = oParams.getParams();
+                var request = '';
+                for (var i = 0; i < params.length; i++) {
+                    var o = params[i];
+                    if (request) {
+                        request += '&';
+                    }
+                    request += o.k + '=' + o.v;
+                }
+                this.requestString = request;
+                return this.requestString;
+            }
+        };
+        return RouteRequestREST;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ServicesRouteRequestModelRouteParamREST);
+    ServicesRouteRequestRouteRequestFactory = function (Logger, ErrorService, RouteRequestOLS, RouteRequestREST) {
+        var RouteRequestFactory = {
+            build: function (options) {
+                var request = null;
+                var settings = options || {};
+                var bOnError = options.onError !== null && typeof options.onError === 'function' ? true : false;
+                var message = null;
+                switch (options.api) {
+                case 'REST':
+                    var myReq = new RouteRequestREST(settings);
+                    if (!myReq.processRequestString()) {
+                        message = 'Error process request (rest) !';
+                        if (bOnError) {
+                            options.onError.call(options.scope, new ErrorService(message));
+                            return;
+                        }
+                        throw new Error(message);
+                    }
+                    request = myReq.requestString;
+                    break;
+                case 'OLS':
+                    request = RouteRequestOLS.build(settings);
+                    if (!request) {
+                        message = 'Error process request (ols) !';
+                        if (bOnError) {
+                            options.onError.call(options.scope, new ErrorService(message));
+                            return;
+                        }
+                        throw new Error(message);
+                    }
+                    break;
+                default:
+                    message = 'Type of API is not supported by service (REST or OLS) !';
+                    if (bOnError) {
+                        options.onError.call(options.scope, new ErrorService(message));
+                        return;
+                    }
+                    throw new Error(message);
+                }
+                return request;
+            }
+        };
+        return RouteRequestFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, ServicesRouteRequestRouteRequestOLS, ServicesRouteRequestRouteRequestREST);
+    FormatsWKT = function (Logger) {
+        var WKT = {
+            toJson: function (strWkt, success, error) {
+                var json = null;
+                try {
+                    if (!strWkt) {
+                        throw new Error('La chaine WKT n\'est pas renseignée !');
+                    }
+                    if (!success) {
+                        success = function (json) {
+                            console.log(json);
+                        };
+                    }
+                    if (!error) {
+                        error = function (e) {
+                            console.log(e);
+                        };
+                    }
+                    var regex;
+                    var subst;
+                    var result;
+                    regex = /(-?\d+\.?[0-9]*)\s(-?\d+\.?[0-9]+)/g;
+                    subst = '[$1,$2]';
+                    strWkt = strWkt.replace(regex, subst);
+                    regex = /^(\w+)/;
+                    result = regex.exec(strWkt);
+                    if (RegExp.$1 === 'POLYGON') {
+                        subst = '{"type" : "Polygon",';
+                        strWkt = strWkt.replace(RegExp.$1, subst);
+                        regex = /(\({2}?)/;
+                        subst = '"coordinates" : [[';
+                        strWkt = strWkt.replace(regex, subst);
+                        regex = /(\){2}?)/;
+                        subst = ']]}';
+                        strWkt = strWkt.replace(regex, subst);
+                        regex = /(\()/g;
+                        subst = '[';
+                        strWkt = strWkt.replace(regex, subst);
+                        regex = /(\))/g;
+                        subst = ']';
+                        strWkt = strWkt.replace(regex, subst);
+                    } else if (RegExp.$1 === 'LINESTRING') {
+                        subst = '{"type" : "LineString",';
+                        strWkt = strWkt.replace(RegExp.$1, subst);
+                        regex = /(\(\(?)/;
+                        subst = '"coordinates" : [';
+                        strWkt = strWkt.replace(regex, subst);
+                        regex = /(\)\)?)/;
+                        subst = ']}';
+                        strWkt = strWkt.replace(regex, subst);
+                    }
+                    json = JSON.parse(strWkt);
+                    if (!json) {
+                        throw new Error('Le JSON est vide !');
+                    }
+                    if (!json.type) {
+                        throw new Error('Le type de geometrie n\'est pas connu !');
+                    }
+                    if (!json.coordinates) {
+                        throw new Error('La liste des points est vide !');
+                    }
+                    success.call(this, json);
+                } catch (e) {
+                    if (e.name === 'SyntaxError') {
+                        error.call(this, 'Erreur de parsing JSON !');
+                        return;
+                    }
+                    error.call(this, e);
+                }
+            }
+        };
+        return WKT;
+    }(UtilsLoggerByDefault);
+    ServicesRouteResponseModelRouteResponse = function () {
+        function RouteResponse() {
+            if (!(this instanceof RouteResponse)) {
+                throw new TypeError('RouteResponse constructor cannot be called as a function.');
+            }
+            this.totalTime = null;
+            this.totalDistance = null;
+            this.bbox = {
+                left: null,
+                right: null,
+                top: null,
+                bottom: null
+            };
+            this.routeGeometry = null;
+            this.routeInstructions = [];
+        }
+        RouteResponse.prototype = { constructor: RouteResponse };
+        return RouteResponse;
+    }();
+    ServicesRouteResponseModelRouteInstruction = function () {
+        function RouteInstruction() {
+            if (!(this instanceof RouteInstruction)) {
+                throw new TypeError('RouteInstruction constructor cannot be called as a function.');
+            }
+            this.duration = null;
+            this.distance = null;
+            this.code = null;
+            this.instruction = null;
+            this.geometry = null;
+        }
+        RouteInstruction.prototype = { constructor: RouteInstruction };
+        return RouteInstruction;
+    }();
+    ServicesRouteFormatsRouteResponseRESTReader = function (Logger, WKT, MessagesResources, ErrSrv, RouteResponse, RouteInstruction) {
+        var RouteResponseRESTReader = {};
+        RouteResponseRESTReader.READERS = {
+            routeResult: function (node) {
+                var response = new RouteResponse();
+                __getChildNodes(node, response);
+                if (response.status === 'error') {
+                    var message = MessagesResources.getMessage('SERVICE_RESPONSE_EXCEPTION', response.message);
+                    throw new ErrSrv({
+                        message: message,
+                        type: ErrSrv.TYPE_SRVERR
+                    });
+                }
+                return response;
+            },
+            status: function (node, response) {
+                var status = __getChildValue(node);
+                if (status === 'ERROR' || status === 'error') {
+                    if (response) {
+                        response.status = 'error';
+                    }
+                }
+            },
+            message: function (node, response) {
+                if (response) {
+                    response.message = __getChildValue(node);
+                }
+            },
+            distance: function (node, response) {
+                if (response) {
+                    response.totalDistance = __getChildValue(node);
+                }
+            },
+            durationSeconds: function (node, response) {
+                if (response) {
+                    response.totalTime = parseFloat(__getChildValue(node));
+                }
+            },
+            bounds: function (node, response) {
+                if (response && response.bbox) {
+                    var coords = __getChildValue(node).split(/[,;]/);
+                    response.bbox.left = parseFloat(coords[0]);
+                    response.bbox.bottom = parseFloat(coords[1]);
+                    response.bbox.right = parseFloat(coords[2]);
+                    response.bbox.top = parseFloat(coords[3]);
+                }
+            },
+            geometryWkt: function (node, response) {
+                if (response) {
+                    var geomWkt = node.innerHTML;
+                    var onWKTSuccess = function (json) {
+                        response.routeGeometry = json;
+                    };
+                    var onWKTError = function () {
+                        var msg = MessagesResources.getMessage('PARAM_FORMAT', ['geometryWkt']);
+                        throw new Error(msg);
+                    };
+                    WKT.toJson(geomWkt, onWKTSuccess, onWKTError);
+                }
+            },
+            step: function (node, response) {
+                var routeInstruction = new RouteInstruction();
+                var name;
+                if (node.hasChildNodes) {
+                    var children = node.childNodes;
+                    var child;
+                    var childName;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (child.nodeType === 1) {
+                            childName = child.localName || child.baseName || child.nodeName;
+                            if (childName === 'durationSeconds') {
+                                routeInstruction.duration = __getChildValue(child);
+                            } else if (childName === 'distance') {
+                                routeInstruction.distance = __getChildValue(child);
+                            } else if (childName === 'navInstruction') {
+                                routeInstruction.code = __getChildValue(child);
+                            } else if (childName === 'name') {
+                                name = __getChildValue(child);
+                            }
+                        }
+                    }
+                }
+                if (routeInstruction.code) {
+                    switch (routeInstruction.code) {
+                    case 'F':
+                        if (name != 'Valeur non renseignée') {
+                            routeInstruction.instruction = 'Tout droit ' + name;
+                        } else {
+                            routeInstruction.instruction = 'Continuer tout droit ';
+                        }
+                        break;
+                    case 'B':
+                        routeInstruction.instruction = 'Demi-tour ' + name;
+                        break;
+                    case 'L':
+                        routeInstruction.instruction = 'Tourner à gauche ' + name;
+                        break;
+                    case 'R':
+                        routeInstruction.instruction = 'Tourner à droite ' + name;
+                        break;
+                    case 'BL':
+                        routeInstruction.instruction = 'Tourner très à gauche ' + name;
+                        break;
+                    case 'BR':
+                        routeInstruction.instruction = 'Tourner très à droite ' + name;
+                        break;
+                    case 'FL':
+                        routeInstruction.instruction = 'Tourner légèrement à gauche ' + name;
+                        break;
+                    case 'FR':
+                        routeInstruction.instruction = 'Tourner légèrement à droite ' + name;
+                        break;
+                    case 'round_about_entry':
+                        routeInstruction.instruction = 'Entrée rond-point ' + name;
+                        break;
+                    case 'round_about_exit':
+                        routeInstruction.instruction = 'Sortie rond-point ' + name;
+                        break;
+                    case null:
+                        routeInstruction.instruction = 'Prendre ' + name;
+                        break;
+                    default:
+                        routeInstruction.instruction = '?' + routeInstruction.code + '? ' + name;
+                        break;
+                    }
+                }
+                if (Array.isArray(response.routeInstructions)) {
+                    response.routeInstructions.push(routeInstruction);
+                }
+            }
+        };
+        RouteResponseRESTReader.read = function (root) {
+            var response;
+            if (root.nodeName === 'routeResult') {
+                response = RouteResponseRESTReader.READERS['routeResult'](root);
+                return response;
+            } else {
+                throw new Error('Erreur lors de la lecture de la réponse : elle n\'est pas au format attendu.');
+            }
+        };
+        function __getChildValue(node) {
+            var textNode;
+            var value = '';
+            if (node.hasChildNodes()) {
+                textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    value = textNode.nodeValue;
+                }
+            }
+            return value;
+        }
+        function __getChildNodes(node, data) {
+            if (node.hasChildNodes()) {
+                var children = node.childNodes;
+                var child;
+                var childName;
+                for (var i = 0; i < children.length; i++) {
+                    child = children[i];
+                    if (child.nodeType === 1) {
+                        childName = child.localName || child.baseName || child.nodeName;
+                        if (RouteResponseRESTReader.READERS[childName]) {
+                            var reader = RouteResponseRESTReader.READERS[childName];
+                            reader(child, data);
+                        } else {
+                            __getChildNodes(child, data);
+                        }
+                    }
+                }
+            }
+        }
+        return RouteResponseRESTReader;
+    }(UtilsLoggerByDefault, FormatsWKT, UtilsMessagesResources, ExceptionsErrorService, ServicesRouteResponseModelRouteResponse, ServicesRouteResponseModelRouteInstruction);
+    ServicesRouteFormatsRouteResponseOLSReader = function (Logger) {
+        var RouteResponseOLSReader = {};
+        RouteResponseOLSReader.READERS = {};
+        RouteResponseOLSReader.read = function (root) {
+        };
+        return RouteResponseOLSReader;
+    }(UtilsLoggerByDefault);
+    ServicesRouteResponseRouteResponseFactory = function (Logger, ErrorService, XML, WKT, MRes, RouteResponseRESTReader, RouteResponseOLSReader, RouteResponse, RouteInstruction) {
+        var RouteResponseFactory = {
+            build: function (options) {
+                var data = null;
+                if (options.response) {
+                    if (options.rawResponse) {
+                        data = options.response;
+                    } else {
+                        switch (options.outputFormat) {
+                        case 'xml':
+                            var routeReader = options.api === 'REST' ? RouteResponseRESTReader : RouteResponseOLSReader;
+                            try {
+                                var p = new XML({ reader: routeReader });
+                                if (typeof options.response === 'string') {
+                                    p.setXMLString(options.response);
+                                } else {
+                                    p.setXMLDoc(options.response);
+                                }
+                                data = p.parse();
+                                if (!data) {
+                                    throw new ErrorService(MRes.getMessage('SERVICE_RESPONSE_FORMAT', 'xml'));
+                                }
+                            } catch (e) {
+                                options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_ANALYSE', options.response)));
+                                return;
+                            }
+                            break;
+                        case 'json':
+                            var JSONResponse;
+                            if (typeof options.response === 'string') {
+                                JSONResponse = window.JSON.parse(options.response);
+                            } else {
+                                JSONResponse = options.response;
+                            }
+                            if (JSONResponse.message) {
+                                options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', JSONResponse.message)));
+                                return;
+                            }
+                            if (JSONResponse) {
+                                var legs = [];
+                                var legSteps = [];
+                                var steps = [];
+                                data = new RouteResponse();
+                                if (data.hasOwnProperty('totalTime')) {
+                                    data.totalTime = parseFloat(JSONResponse.durationSeconds);
+                                }
+                                if (data.hasOwnProperty('totalDistance')) {
+                                    data.totalDistance = options.distanceUnit === 'm' ? JSONResponse.distanceMeters : JSONResponse.distance;
+                                }
+                                if (data.hasOwnProperty('bbox')) {
+                                    var coords = JSONResponse.bounds.split(/[,;]/);
+                                    data.bbox.left = parseFloat(coords[0]);
+                                    data.bbox.bottom = parseFloat(coords[1]);
+                                    data.bbox.right = parseFloat(coords[2]);
+                                    data.bbox.top = parseFloat(coords[3]);
+                                }
+                                var onWKTSuccess = function (json) {
+                                    data.routeGeometry = json;
+                                };
+                                var onWKTError = function (e) {
+                                    console.log(e);
+                                    options.onError.call(options.scope, new ErrorService(MRes.getMessage('PARAM_FORMAT', ['geometryWkt'])));
+                                };
+                                if (data.hasOwnProperty('routeGeometry')) {
+                                    var geometry = JSONResponse.geometryWkt || JSONResponse.simplifiedWkt;
+                                    if (geometry) {
+                                        WKT.toJson(geometry, onWKTSuccess, onWKTError);
+                                        if (!data.routeGeometry) {
+                                            return;
+                                        }
+                                    }
+                                }
+                                if (data.hasOwnProperty('routeInstructions')) {
+                                    var legList = JSONResponse.legs;
+                                    var i;
+                                    if (Array.isArray(legList) && legList.length) {
+                                        for (i = 0; i < legList.length; i++) {
+                                            legs.push(legList[i]);
+                                        }
+                                    }
+                                    if (Array.isArray(legs) && legs.length) {
+                                        for (i = 0; i < legs.length; i++) {
+                                            legSteps.push(legs[i].steps);
+                                        }
+                                    }
+                                    if (Array.isArray(legSteps) && legSteps.length) {
+                                        for (i = 0; i < legSteps.length; i++) {
+                                            steps = steps.concat(legSteps[i]);
+                                        }
+                                    }
+                                    steps.forEach(function (step) {
+                                        data.routeInstructions.push(new RouteInstruction());
+                                        data.routeInstructions[data.routeInstructions.length - 1].duration = step.durationSeconds;
+                                        data.routeInstructions[data.routeInstructions.length - 1].distance = options.distanceUnit === 'm' ? step.distanceMeters : step.distance;
+                                        data.routeInstructions[data.routeInstructions.length - 1].code = step.navInstruction;
+                                        var points = [];
+                                        for (var i = 0; i < step.points.length; i++) {
+                                            var point = step.points[i].split(',');
+                                            if (point) {
+                                                points.push(point);
+                                            }
+                                        }
+                                        if (points && points.length !== 0) {
+                                            data.routeInstructions[data.routeInstructions.length - 1].geometry = {
+                                                coordinates: points,
+                                                type: 'LineString'
+                                            };
+                                        } else {
+                                            data.routeInstructions[data.routeInstructions.length - 1].geometry = null;
+                                        }
+                                        if (step.name == 'Valeur non renseignée') {
+                                            step.name = '';
+                                        }
+                                        switch (step.navInstruction) {
+                                        case 'F':
+                                            if (step.name) {
+                                                data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Tout droit ' + step.name;
+                                            } else {
+                                                data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Continuer tout droit ';
+                                            }
+                                            break;
+                                        case 'B':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Demi-tour ' + step.name;
+                                            break;
+                                        case 'L':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Tourner à gauche ' + step.name;
+                                            break;
+                                        case 'R':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Tourner à droite ' + step.name;
+                                            break;
+                                        case 'BL':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Tourner très à gauche ' + step.name;
+                                            break;
+                                        case 'BR':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Tourner très à droite ' + step.name;
+                                            break;
+                                        case 'FL':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Tourner légèrement à gauche ' + step.name;
+                                            break;
+                                        case 'FR':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Tourner légèrement à droite ' + step.name;
+                                            break;
+                                        case 'round_about_entry':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Entrée rond-point ' + step.name;
+                                            break;
+                                        case 'round_about_exit':
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Sortie rond-point ' + step.name;
+                                            break;
+                                        case null:
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = 'Prendre tout droit ' + step.name;
+                                            break;
+                                        default:
+                                            data.routeInstructions[data.routeInstructions.length - 1].instruction = '?' + step.navInstruction + '? ' + step.name;
+                                            break;
+                                        }
+                                    });
+                                }
+                            }
+                            if (!data) {
+                                options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_ANALYSE', 'json')));
+                                return;
+                            }
+                            break;
+                        default:
+                            options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_FORMAT', 'json', 'xml')));
+                            return;
+                        }
+                        if (data && data.exceptionReport) {
+                            options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EXCEPTION_2')));
+                            return;
+                        }
+                    }
+                } else {
+                    options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EMPTY')));
+                    return;
+                }
+                options.onSuccess.call(options.scope, data);
+                return;
+            }
+        };
+        return RouteResponseFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, FormatsXML, FormatsWKT, UtilsMessagesResources, ServicesRouteFormatsRouteResponseRESTReader, ServicesRouteFormatsRouteResponseOLSReader, ServicesRouteResponseModelRouteResponse, ServicesRouteResponseModelRouteInstruction);
+    ServicesRouteRoute = function (Logger, _, ErrorService, CommonService, DefaultUrlService, RouteRequestFactory, RouteResponseFactory) {
+        function Route(options) {
+            if (!(this instanceof Route)) {
+                throw new TypeError(_.getMessage('CLASS_CONSTRUCTOR', 'Route'));
+            }
+            this.CLASSNAME = 'Route';
+            CommonService.apply(this, arguments);
+            if (!options.startPoint) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'startPoint'));
+            }
+            if (options.startPoint.x == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'startPoint.x'));
+            }
+            if (options.startPoint.y == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'startPoint.y'));
+            }
+            if (!options.endPoint) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'endPoint'));
+            }
+            if (options.endPoint.x == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'endPoint.x'));
+            }
+            if (options.endPoint.y == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'endPoint.y'));
+            }
+            this.options.api = typeof options.api == 'string' ? options.api.toUpperCase() : 'REST';
+            this.options.outputFormat = typeof options.outputFormat == 'string' ? options.outputFormat.toLowerCase() : 'json';
+            this.options.startPoint = options.startPoint;
+            this.options.endPoint = options.endPoint;
+            this.options.viaPoints = options.viaPoints || null;
+            this.options.exclusions = options.exclusions || null;
+            this.options.routePreference = options.routePreference || 'fastest';
+            this.options.graph = options.graph || 'Voiture';
+            this.options.geometryInInstructions = options.geometryInInstructions || false;
+            this.options.provideBbox = options.provideBbox || true;
+            this.options.distanceUnit = options.distanceUnit || 'km';
+            this.options.expectedStartTime = null;
+            this.options.srs = options.srs || 'EPSG:4326';
+            this.options.api = 'REST';
+            if (this.options.protocol === 'XHR') {
+                this.options.httpMethod = 'GET';
+            }
+            if (!this.options.serverUrl) {
+                var lstUrlByDefault = DefaultUrlService.Route.url(this.options.apiKey);
+                var urlFound = null;
+                switch (this.options.api) {
+                case 'OLS':
+                    urlFound = lstUrlByDefault.ols;
+                    break;
+                case 'REST':
+                    var key = 'route' + '-' + this.options.outputFormat;
+                    urlFound = lstUrlByDefault[key];
+                    break;
+                default:
+                    throw new Error(_.getMessage('PARAM_UNKNOWN', 'api'));
+                }
+                if (!urlFound) {
+                    throw new Error('Url by default not found !');
+                }
+                this.options.serverUrl = urlFound;
+            }
+            var idx = this.options.serverUrl.lastIndexOf('.');
+            if (idx !== -1) {
+                var extension = this.options.serverUrl.substring(idx + 1);
+                if (extension && extension.length < 5) {
+                    switch (extension.toLowerCase()) {
+                    case 'json':
+                    case 'xml':
+                        this.options.outputFormat = extension.toLowerCase();
+                        break;
+                    default:
+                        throw new Error('type of service : unknown or unsupported (json or xml) !');
+                    }
+                }
+            }
+        }
+        Route.prototype = Object.create(CommonService.prototype, {});
+        Route.prototype.constructor = Route;
+        Route.prototype.buildRequest = function (error, success) {
+            var options = {
+                api: this.options.api,
+                startPoint: this.options.startPoint,
+                endPoint: this.options.endPoint,
+                viaPoints: this.options.viaPoints,
+                provideBbox: this.options.provideBbox,
+                exclusions: this.options.exclusions,
+                distanceUnit: this.options.distanceUnit,
+                graph: this.options.graph,
+                geometryInInstructions: this.options.geometryInInstructions,
+                routePreference: this.options.routePreference,
+                srs: this.options.srs
+            };
+            this.request = RouteRequestFactory.build(options);
+            if (!this.request) {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_REQUEST_BUILD')));
+            } else {
+                success.call(this, this.request);
+            }
+        };
+        Route.prototype.analyzeResponse = function (error, success) {
+            if (this.response) {
+                var options = {
+                    distanceUnit: this.options.distanceUnit,
+                    response: this.response,
+                    outputFormat: this.options.outputFormat,
+                    api: this.options.api,
+                    rawResponse: this.options.rawResponse,
+                    onError: error,
+                    onSuccess: success,
+                    scope: this
+                };
+                RouteResponseFactory.build(options);
+            } else {
+                error.call(this, new ErrorService(_.getMessage('SERVICE_RESPONSE_EMPTY')));
+            }
+        };
+        return Route;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, ServicesCommonService, ServicesDefaultUrlService, ServicesRouteRequestRouteRequestFactory, ServicesRouteResponseRouteResponseFactory);
+    ServicesProcessIsoCurveRequestModelProcessIsoCurveParam = function (Logger) {
+        function ProcessIsoCurveParam(options) {
+            if (!(this instanceof ProcessIsoCurveParam)) {
+                throw new TypeError('ProcessIsoCurveParam constructor cannot be called as a function.');
+            }
+            this.options = options || {};
+            this.id = this.options.id;
+            this.location = this.options.position;
+            this.srs = this.options.srs;
+            this.graphName = this.options.graph;
+            this.profileId = this.options.profileId || null;
+            this.profileName = this.options.profileName || null;
+            this.exclusions = this.options.exclusions;
+            this.reverse = this.options.reverse;
+            this.smoothing = this.options.smoothing;
+            this.holes = this.options.holes;
+            var value = this.options.method;
+            switch (value) {
+            case 'time':
+                this.method = 'time';
+                this.time = this.options.time;
+                break;
+            case 'distance':
+                this.method = 'distance';
+                this.distance = this.options.distance;
+                break;
+            default:
+                this.method = 'time';
+            }
+        }
+        ProcessIsoCurveParam.CLASSNAME = 'ProcessIsoCurveParam';
+        ProcessIsoCurveParam.prototype = {
+            constructor: ProcessIsoCurveParam,
+            getLocation: function () {
+                return this.location.x + ',' + this.location.y;
+            },
+            getExclusions: function () {
+                return this.exclusions.join(';');
+            }
+        };
+        ProcessIsoCurveParam.prototype.getParams = function () {
+            var map = [];
+            map.push({
+                k: 'location',
+                v: this.getLocation()
+            });
+            map.push({
+                k: 'smoothing',
+                v: this.smoothing
+            });
+            map.push({
+                k: 'holes',
+                v: this.holes
+            });
+            map.push({
+                k: 'reverse',
+                v: this.reverse
+            });
+            map.push({
+                k: 'method',
+                v: this.method
+            });
+            if (this.time) {
+                map.push({
+                    k: 'time',
+                    v: this.time
+                });
+            }
+            if (this.distance) {
+                map.push({
+                    k: 'distance',
+                    v: this.distance
+                });
+            }
+            map.push({
+                k: 'graphName',
+                v: this.graphName
+            });
+            if (this.exclusions) {
+                map.push({
+                    k: 'exclusions',
+                    v: this.getExclusions()
+                });
+            }
+            if (this.srs) {
+                map.push({
+                    k: 'srs',
+                    v: this.srs
+                });
+            }
+            return map;
+        };
+        return ProcessIsoCurveParam;
+    }(UtilsLoggerByDefault);
+    ServicesProcessIsoCurveRequestProcessIsoCurveRequest = function (Logger, _, ProcessIsoCurveParam) {
+        function ProcessIsoCurveRequest(options) {
+            if (!(this instanceof ProcessIsoCurveRequest)) {
+                throw new TypeError('ProcessIsoCurveRequest constructor cannot be called as a function.');
+            }
+            if (!options) {
+                throw new Error(_.getMessage('PARAM_EMPTY', 'options'));
+            }
+            this.settings = options;
+            this.mode = this.settings.httpMethod || 'GET';
+        }
+        ProcessIsoCurveRequest.prototype = {
+            requestString: null,
+            constructor: ProcessIsoCurveRequest,
+            template: {
+                container: '<?xml version="1.0" encoding="UTF-8"?>\n' + '<isochroneRequest>\n' + '__ID__' + '\t<location>\n' + '\t\t<x>__X__</x>\n' + '\t\t<y>__Y__</y>\n' + '\t</location>\n' + '\t<srs>__SRS__</srs>\n' + '\t<graphName>__GRAPHNAME__</graphName>\n' + '__PROFIL__' + '__EXCLUSIONS__' + '\t<method>__METHOD__</method>\n' + '__TIME__' + '__DISTANCE__' + '\t<reverse>__REVERSE__</reverse>\n' + '\t<smoothing>__SMOOTHING__</smoothing>\n' + '\t<holes>__HOLES__</holes>\n' + '</isochroneRequest>',
+                id: '\t<id>__IDVALUE__</id>\n',
+                profil: '\t<profileId>__PROFILID__</profileId>\n' + '\t<profileName>__PROFILNAME__</profileName>\n',
+                exclusions: {
+                    container: '\t<exclusions>\n' + '__EXCLUSIONFEATURE__\n' + '\t</exclusions>\n',
+                    feature: '\t\t<exclusion>__EXCLUSIONVALUE__</exclusion>'
+                },
+                time: '\t<time>__TIMEVALUE__</time>\n',
+                distance: '\t<distance>__DISTANCEVALUE__</distance>\n'
+            },
+            processRequestString: function () {
+                var request = '';
+                var i = 0;
+                switch (this.mode) {
+                case 'GET':
+                    var oParams = new ProcessIsoCurveParam(this.settings);
+                    var params = oParams.getParams();
+                    for (i = 0; i < params.length; i++) {
+                        var o = params[i];
+                        if (request) {
+                            request += '&';
+                        }
+                        request += o.k + '=' + o.v;
+                    }
+                    break;
+                case 'POST':
+                    request = this.template.container;
+                    request = request.replace(/__ID__/g, '');
+                    request = request.replace(/__PROFIL__/g, '');
+                    request = request.replace(/__X__/g, this.settings.position.x);
+                    request = request.replace(/__Y__/g, this.settings.position.y);
+                    request = request.replace(/__GRAPHNAME__/g, this.settings.graph);
+                    request = request.replace(/__SRS__/g, this.settings.srs);
+                    request = request.replace(/__SMOOTHING__/g, this.settings.smoothing);
+                    request = request.replace(/__HOLES__/g, this.settings.holes);
+                    request = request.replace(/__REVERSE__/g, this.settings.reverse);
+                    if (this.settings.exclusions) {
+                        var tmplExclusions = this.template.exclusions.container;
+                        var exclusions = [];
+                        for (i = 0; i < this.settings.exclusions.length; i++) {
+                            var tmplFeature = this.template.exclusions.feature;
+                            tmplFeature = tmplFeature.replace(/__EXCLUSIONVALUE__/, this.settings.exclusions[i]);
+                            exclusions.push(tmplFeature);
+                        }
+                        tmplExclusions = tmplExclusions.replace(/__EXCLUSIONFEATURE__/, exclusions.join('\n'));
+                        request = request.replace(/__EXCLUSIONS__/g, tmplExclusions);
+                    }
+                    request = request.replace(/__EXCLUSIONS__/g, '');
+                    if (this.settings.distance) {
+                        var tmplDistance = this.template.distance;
+                        tmplDistance = tmplDistance.replace(/__DISTANCEVALUE__/g, this.settings.distance);
+                        request = request.replace(/__DISTANCE__/g, tmplDistance);
+                        request = request.replace(/__METHOD__/g, 'distance');
+                    }
+                    request = request.replace(/__DISTANCE__/g, '');
+                    if (this.settings.time) {
+                        var tmplTime = this.template.time;
+                        tmplTime = tmplTime.replace(/__TIMEVALUE__/g, this.settings.time);
+                        request = request.replace(/__TIME__/g, tmplTime);
+                        request = request.replace(/__METHOD__/g, 'time');
+                    }
+                    request = request.replace(/__TIME__/g, '');
+                    break;
+                default:
+                }
+                this.requestString = request;
+                return this.requestString;
+            }
+        };
+        return ProcessIsoCurveRequest;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ServicesProcessIsoCurveRequestModelProcessIsoCurveParam);
+    ServicesProcessIsoCurveResponseModelProcessIsoCurveResponse = function () {
+        function ProcessIsoCurveResponse() {
+            if (!(this instanceof ProcessIsoCurveResponse)) {
+                throw new TypeError('ProcessIsoCurveResponse constructor cannot be called as a function.');
+            }
+            this.message = null;
+            this.id = null;
+            this.location = {};
+            this.location.x = null;
+            this.location.y = null;
+            this.srs = null;
+            this.geometry = null;
+            this.time = null;
+            this.distance = null;
+        }
+        ProcessIsoCurveResponse.prototype = { constructor: ProcessIsoCurveResponse };
+        return ProcessIsoCurveResponse;
+    }();
+    ServicesProcessIsoCurveFormatsProcessIsoCurveResponseReader = function (Logger, WKT, ErrSrv, MessagesResources, ProcessIsoCurveResponse) {
+        var ProcessIsoCurveResponseReader = {};
+        ProcessIsoCurveResponseReader.READERS = {
+            isochronResult: function (root) {
+                var response = new ProcessIsoCurveResponse();
+                if (root.hasChildNodes()) {
+                    var children = root.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (ProcessIsoCurveResponseReader.READERS[child.nodeName]) {
+                            ProcessIsoCurveResponseReader.READERS[child.nodeName](child, response);
+                        }
+                    }
+                }
+                if (response.status === 'error') {
+                    var message = MessagesResources.getMessage('SERVICE_RESPONSE_EXCEPTION', response.message);
+                    throw new ErrSrv({
+                        message: message,
+                        type: ErrSrv.TYPE_SRVERR
+                    });
+                }
+                return response;
+            },
+            message: function (node, response) {
+                if (response) {
+                    response.message = __getChildValue(node);
+                }
+            },
+            status: function (node, response) {
+                var status = __getChildValue(node);
+                if (status === 'ERROR' || status === 'error') {
+                    if (response) {
+                        response.status = 'error';
+                    }
+                }
+            },
+            id: function (node, response) {
+                if (response) {
+                    response.id = __getChildValue(node);
+                }
+            },
+            location: function (node, response) {
+                var coords = __getChildValue(node);
+                if (response && response.location) {
+                    response.location.x = parseFloat(coords.split(',')[0]);
+                    response.location.y = parseFloat(coords.split(',')[1]);
+                }
+            },
+            srs: function (node, response) {
+                if (response) {
+                    response.srs = __getChildValue(node);
+                }
+            },
+            distance: function (node, response) {
+                if (response) {
+                    response.distance = parseFloat(__getChildValue(node));
+                }
+            },
+            time: function (node, response) {
+                if (response) {
+                    response.time = parseFloat(__getChildValue(node));
+                }
+            },
+            wktGeometry: function (node, response) {
+                if (response) {
+                    var wktGeometry = node.innerHTML;
+                    var onWKTSuccess = function (json) {
+                        response.geometry = json;
+                    };
+                    var onWKTError = function () {
+                        var msg = MessagesResources.getMessage('PARAM_FORMAT', ['wktGeometry']);
+                        throw new Error(msg);
+                    };
+                    if (response.hasOwnProperty('geometry')) {
+                        WKT.toJson(wktGeometry, onWKTSuccess, onWKTError);
+                    }
+                }
+            },
+            serviceResult: function (node) {
+                var response = {};
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (ProcessIsoCurveResponseReader.READERS[child.nodeName]) {
+                            ProcessIsoCurveResponseReader.READERS[child.nodeName](child, response);
+                        }
+                    }
+                }
+                return response;
+            },
+            ExceptionReport: function (node) {
+                var response = {};
+                if (node.hasChildNodes()) {
+                    var children = node.childNodes;
+                    var child;
+                    for (var i = 0; i < children.length; i++) {
+                        child = children[i];
+                        if (child.nodeName === 'Exception') {
+                            response.exceptionReport = ProcessIsoCurveResponseReader.READERS['Exception'](child);
+                        }
+                    }
+                }
+                return response;
+            },
+            Exception: function (node) {
+                var exceptionReport = {};
+                var exceptionCode = node.getAttribute('exceptionCode');
+                if (exceptionCode) {
+                    exceptionReport.exceptionCode = exceptionCode;
+                }
+                var textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    exceptionReport.exception = textNode.nodeValue;
+                }
+                return exceptionReport;
+            }
+        };
+        ProcessIsoCurveResponseReader.read = function (root) {
+            var response;
+            if (root.nodeName === 'isochronResult' || root.nodeName === 'isochroneResult' || root.nodeName === 'IsochroneResult') {
+                response = ProcessIsoCurveResponseReader.READERS['isochronResult'](root);
+                return response;
+            } else if (root.nodeName === 'ExceptionReport') {
+                response = ProcessIsoCurveResponseReader.READERS[root.nodeName](root);
+                return response;
+            } else if (ProcessIsoCurveResponseReader.READERS[root.nodeName]) {
+                response = ProcessIsoCurveResponseReader.READERS[root.nodeName](root);
+                if (response.status === 'error') {
+                    var errMsg = MessagesResources.getMessage('SERVICE_RESPONSE_EXCEPTION', response.message);
+                    throw new ErrSrv({
+                        message: errMsg,
+                        type: ErrSrv.TYPE_SRVERR
+                    });
+                }
+                return response;
+            } else {
+                throw new ErrSrv({
+                    message: MessagesResources.getMessage('SERVICE_RESPONSE_ANALYSE', root.nodeName),
+                    type: ErrSrv.TYPE_UNKERR
+                });
+            }
+        };
+        function __getChildValue(node) {
+            var textNode;
+            var value = '';
+            if (node.hasChildNodes()) {
+                textNode = node.firstChild;
+                if (textNode && textNode.nodeType === 3) {
+                    value = textNode.nodeValue;
+                }
+            }
+            return value;
+        }
+        return ProcessIsoCurveResponseReader;
+    }(UtilsLoggerByDefault, FormatsWKT, ExceptionsErrorService, UtilsMessagesResources, ServicesProcessIsoCurveResponseModelProcessIsoCurveResponse);
+    ServicesProcessIsoCurveResponseProcessIsoCurveResponseFactory = function (Logger, ErrorService, MRes, XML, WKT, ProcessIsoCurveResponseReader, ProcessIsoCurveResponse) {
+        var ProcessIsoCurveResponseFactory = {
+            build: function (options) {
+                var data = null;
+                if (options.response) {
+                    if (options.rawResponse) {
+                        data = options.response;
+                    } else {
+                        switch (options.outputFormat) {
+                        case 'xml':
+                            try {
+                                var p = new XML({ reader: ProcessIsoCurveResponseReader });
+                                if (typeof options.response === 'string') {
+                                    p.setXMLString(options.response);
+                                } else {
+                                    p.setXMLDoc(options.response);
+                                }
+                                data = p.parse();
+                                if (!data) {
+                                    throw new Error(MRes.getMessage('SERVICE_RESPONSE_EXCEPTION_2'));
+                                }
+                            } catch (e) {
+                                var message = e.message;
+                                message += '\n(raw response service : \'' + options.response + '\')';
+                                options.onError.call(options.scope, new ErrorService({
+                                    message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', message),
+                                    status: 200,
+                                    type: ErrorService.TYPE_SRVERR
+                                }));
+                                return;
+                            }
+                            break;
+                        case 'json':
+                            var JSONResponse;
+                            if (typeof options.response === 'string') {
+                                JSONResponse = window.JSON.parse(options.response);
+                            } else {
+                                JSONResponse = options.response;
+                            }
+                            if (JSONResponse.status === 'OK' || JSONResponse.status === 'ok') {
+                                data = new ProcessIsoCurveResponse();
+                                if (data) {
+                                    data.time = JSONResponse.time;
+                                    data.distance = JSONResponse.distance;
+                                    data.message = JSONResponse.message;
+                                    data.id = JSONResponse.id;
+                                    data.srs = JSONResponse.srs;
+                                    var onWKTSuccess = function (json) {
+                                        data.geometry = json;
+                                    };
+                                    var onWKTError = function () {
+                                        options.onError.call(options.scope, new ErrorService({ message: MRes.getMessage('PARAM_FORMAT', 'wktGeometry') }));
+                                    };
+                                    if (data.hasOwnProperty('geometry')) {
+                                        WKT.toJson(JSONResponse.wktGeometry, onWKTSuccess, onWKTError);
+                                        if (!data.geometry) {
+                                            return;
+                                        }
+                                    }
+                                    var coords = JSONResponse.location.split(',');
+                                    if (data.location) {
+                                        data.location.x = coords[0];
+                                        data.location.y = coords[1];
+                                    }
+                                } else {
+                                    options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_ANALYSE', options.response)));
+                                    return;
+                                }
+                            } else if (JSONResponse.status === 'ERROR' || JSONResponse.status === 'error') {
+                                var mess = JSONResponse.message;
+                                mess += '\n(raw response service : \'' + JSONResponse + '\')';
+                                options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', mess)));
+                                return;
+                            }
+                            break;
+                        default:
+                            options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_FORMAT', 'json', 'xml')));
+                            return;
+                        }
+                        if (data && data.exceptionReport) {
+                            options.onError.call(options.scope, new ErrorService({
+                                message: MRes.getMessage('SERVICE_RESPONSE_EXCEPTION', data.exceptionReport),
+                                type: ErrorService.TYPE_SRVERR,
+                                status: 200
+                            }));
+                            return;
+                        }
+                    }
+                } else {
+                    options.onError.call(options.scope, new ErrorService(MRes.getMessage('SERVICE_RESPONSE_EMPTY')));
+                    return;
+                }
+                options.onSuccess.call(options.scope, data);
+                return;
+            }
+        };
+        return ProcessIsoCurveResponseFactory;
+    }(UtilsLoggerByDefault, ExceptionsErrorService, UtilsMessagesResources, FormatsXML, FormatsWKT, ServicesProcessIsoCurveFormatsProcessIsoCurveResponseReader, ServicesProcessIsoCurveResponseModelProcessIsoCurveResponse);
+    ServicesProcessIsoCurveProcessIsoCurve = function (Logger, _, ErrorService, CommonService, DefaultUrlService, ProcessIsoCurveRequest, ProcessIsoCurveResponseFactory) {
+        function ProcessIsoCurve(options) {
+            if (!(this instanceof ProcessIsoCurve)) {
+                throw new TypeError(_.getMessage('CLASS_CONSTRUCTOR', 'ProcessIsoCurve'));
+            }
+            this.CLASSNAME = 'ProcessIsoCurve';
+            CommonService.apply(this, arguments);
+            if (!options.position) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'position'));
+            }
+            if (options.position.x == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'position.x'));
+            }
+            if (options.position.y == null) {
+                throw new Error(_.getMessage('PARAM_MISSING', 'position.y'));
+            }
+            if (!options.time && !options.distance) {
+                throw new Error('Parameter(s) \'distance\' missing. Parameter time to calculate an isochrone, parameter distance for an isodistance');
+            }
+            if (!options.time && options.distance) {
+                this.options.method = 'distance';
+                if (this.options.time) {
+                    delete this.options.time;
+                }
+            }
+            if (options.time && !options.distance) {
+                this.options.method = 'time';
+                if (this.options.distance) {
+                    delete this.options.distance;
+                }
+            }
+            this.options.method = this.options.method || 'time';
+            this.options.exclusions = options.exclusions || null;
+            this.options.graph = options.graph || 'Voiture';
+            this.options.reverse = options.reverse || false;
+            this.options.smoothing = options.smoothing || false;
+            this.options.holes = options.holes || false;
+            this.options.srs = options.srs || 'EPSG:4326';
+            this.options.outputFormat = typeof options.outputFormat == 'string' ? options.outputFormat.toLowerCase() : 'json';
+            if (!this.options.serverUrl) {
+                var lstUrlByDefault = DefaultUrlService.ProcessIsoCurve.url(this.options.apiKey);
+                var urlFound = lstUrlByDefault['iso' + '-' + this.options.outputFormat];
+                if (!urlFound) {
+                    throw new Error('Url by default not found !');
+                }
+                this.options.serverUrl = urlFound;
+            }
+            var idx = this.options.serverUrl.lastIndexOf('.');
+            if (idx !== -1) {
+                var extension = this.options.serverUrl.substring(idx + 1);
+                if (extension && extension.length < 5) {
+                    switch (extension.toLowerCase()) {
+                    case 'json':
+                    case 'xml':
+                        this.options.outputFormat = extension.toLowerCase();
+                        break;
+                    default:
+                        throw new Error('type of service : unknown or unsupported (json or xml) !');
+                    }
+                }
+            }
+        }
+        ProcessIsoCurve.prototype = Object.create(CommonService.prototype, {});
+        ProcessIsoCurve.prototype.constructor = ProcessIsoCurve;
+        ProcessIsoCurve.prototype.buildRequest = function (error, success) {
+            try {
+                var oIsoCurve = new ProcessIsoCurveRequest(this.options);
+                if (!oIsoCurve.processRequestString()) {
+                    throw new Error(_.getMessage('SERVICE_REQUEST_BUILD'));
+                }
+                this.request = oIsoCurve.requestString;
+            } catch (e) {
+                error.call(this, new ErrorService(e.message));
+                return;
+            }
+            success.call(this, this.request);
+        };
+        ProcessIsoCurve.prototype.analyzeResponse = function (onError, onSuccess) {
+            if (this.response) {
+                var options = {
+                    response: this.response,
+                    outputFormat: this.options.outputFormat,
+                    rawResponse: this.options.rawResponse,
+                    onSuccess: onSuccess,
+                    onError: onError,
+                    scope: this
+                };
+                ProcessIsoCurveResponseFactory.build(options);
+            } else {
+                onError.call(this, new ErrorService(_.getMessage('SERVICE_RESPONSE_EMPTY')));
+            }
+        };
+        return ProcessIsoCurve;
+    }(UtilsLoggerByDefault, UtilsMessagesResources, ExceptionsErrorService, ServicesCommonService, ServicesDefaultUrlService, ServicesProcessIsoCurveRequestProcessIsoCurveRequest, ServicesProcessIsoCurveResponseProcessIsoCurveResponseFactory);
+    ServicesServices = function (Alti, AutoConf, Geocode, ReverseGeocode, AutoComplete, Route, ProcessIsoCurve) {
+        var Services = {
+            getConfig: function (options) {
+                var autoconfService = new AutoConf(options);
+                autoconfService.call();
+            },
+            getAltitude: function (options) {
+                var altiService = new Alti(options);
+                altiService.call();
+            },
+            geocode: function (options) {
+                var geocodeService = new Geocode(options);
+                geocodeService.call();
+            },
+            reverseGeocode: function (options) {
+                var reverseGeocodeService = new ReverseGeocode(options);
+                reverseGeocodeService.call();
+            },
+            autoComplete: function (options) {
+                var autoCompleteService = new AutoComplete(options);
+                autoCompleteService.call();
+            },
+            route: function (options) {
+                var routeService = new Route(options);
+                routeService.call();
+            },
+            isoCurve: function (options) {
+                var processIsoCurveService = new ProcessIsoCurve(options);
+                processIsoCurveService.call();
+            }
+        };
+        var point = {};
+        var circle = {};
+        var bbox = {};
+        return Services;
+    }(ServicesAltiAlti, ServicesAutoConfAutoConf, ServicesGeocodeGeocode, ServicesGeocodeReverseGeocode, ServicesAutoCompleteAutoComplete, ServicesRouteRoute, ServicesProcessIsoCurveProcessIsoCurve);
+    Gp = function (XHR, Services, AltiResponse, Elevation, AutoCompleteResponse, SuggestedLocation, GetConfigResponse, Constraint, Format, Layer, Legend, Metadata, Originator, Service, Style, Territory, Thematic, TM, TMLimit, TMS, GeocodeResponse, GeocodedLocation, DirectGeocodedLocation, ReverseGeocodedLocation, IsoCurveResponse, RouteResponse, RouteInstruction, Error, Helper) {
+        var scope = typeof window !== 'undefined' ? window : {};
+        var Gp = scope.Gp || {
+            servicesVersion: '1.0.0-beta3',
+            servicesDate: '2016-12-01',
+            extend: function (strNS, value) {
+                var parts = strNS.split('.');
+                var parent = this;
+                var pl;
+                pl = parts.length;
+                for (var i = 0; i < pl; i++) {
+                    if (typeof parent[parts[i]] === 'undefined') {
+                        parent[parts[i]] = {};
+                    }
+                    var n = pl - 1;
+                    if (i === n) {
+                        parent[parts[i]] = value;
+                    }
+                    parent = parent[parts[i]];
+                }
+                return this;
+            }
+        };
+        Gp.extend('Protocols', {});
+        Gp.extend('Protocols.XHR', XHR);
+        Gp.extend('Services', Services);
+        Gp.extend('Services.AltiResponse', AltiResponse);
+        Gp.extend('Services.Alti.Elevation', Elevation);
+        Gp.extend('Services.AutoCompleteResponse', AutoCompleteResponse);
+        Gp.extend('Services.AutoComplete.SuggestedLocation', SuggestedLocation);
+        Gp.extend('Services.GetConfigResponse', GetConfigResponse);
+        Gp.extend('Services.Config.Constraint', Constraint);
+        Gp.extend('Services.Config.Format', Format);
+        Gp.extend('Services.Config.Layer', Layer);
+        Gp.extend('Services.Config.Legend', Legend);
+        Gp.extend('Services.Config.Metadata', Metadata);
+        Gp.extend('Services.Config.Originator', Originator);
+        Gp.extend('Services.Config.Service', Service);
+        Gp.extend('Services.Config.Style', Style);
+        Gp.extend('Services.Config.Territory', Territory);
+        Gp.extend('Services.Config.Thematic', SuggestedLocation);
+        Gp.extend('Services.Config.TileMatrix', TM);
+        Gp.extend('Services.Config.TileMatrixLimit', TMLimit);
+        Gp.extend('Services.Config.TileMatrixSet', TMS);
+        Gp.extend('Services.GeocodeResponse', GeocodeResponse);
+        Gp.extend('Services.Geocode.GeocodedLocation', GeocodedLocation);
+        Gp.extend('Services.Geocode.DirectGeocodedLocation', DirectGeocodedLocation);
+        Gp.extend('Services.Geocode.ReverseGeocodedLocation', ReverseGeocodedLocation);
+        Gp.extend('Services.IsoCurveResponse', IsoCurveResponse);
+        Gp.extend('Services.RouteResponse', RouteResponse);
+        Gp.extend('Services.Route.RouteInstruction', RouteInstruction);
+        Gp.extend('Error', Error);
+        Gp.extend('Helper', Helper);
+        scope.Gp = Gp;
+        return scope.Gp;
+    }(ProtocolsXHR, ServicesServices, ServicesAltiResponseModelAltiResponse, ServicesAltiResponseModelElevation, ServicesAutoCompleteResponseModelAutoCompleteResponse, ServicesAutoCompleteResponseModelSuggestedLocation, ServicesAutoConfResponseModelAutoConfResponse, ServicesAutoConfResponseModelConstraint, ServicesAutoConfResponseModelFormat, ServicesAutoConfResponseModelLayer, ServicesAutoConfResponseModelLegend, ServicesAutoConfResponseModelMetadata, ServicesAutoConfResponseModelOriginator, ServicesAutoConfResponseModelService, ServicesAutoConfResponseModelStyle, ServicesAutoConfResponseModelTerritory, ServicesAutoConfResponseModelThematic, ServicesAutoConfResponseModelTileMatrix, ServicesAutoConfResponseModelTileMatrixLimit, ServicesAutoConfResponseModelTileMatrixSet, ServicesGeocodeResponseModelGeocodeResponse, ServicesGeocodeResponseModelGeocodedLocation, ServicesGeocodeResponseModelDirectGeocodedLocation, ServicesGeocodeResponseModelReverseGeocodedLocation, ServicesProcessIsoCurveResponseModelProcessIsoCurveResponse, ServicesRouteResponseModelRouteResponse, ServicesRouteResponseModelRouteInstruction, ExceptionsErrorService, UtilsHelper);
+    return Gp;
+}));
+CommonUtilsAutoLoadConfig = function (Gp) {
+    (function () {
+        var scripts = document.getElementsByTagName('script');
+        var key = scripts[scripts.length - 1].getAttribute('data-key');
+        if (key) {
+            var splitKeys = key.split(/;|,|\|/);
+            if (key && splitKeys.length > 1) {
+                var keys = [];
+                for (var i = 0; i < splitKeys.length; i++) {
+                    keys.push(splitKeys[i]);
+                }
+                key = keys;
+            }
+        }
+        var url = scripts[scripts.length - 1].getAttribute('data-url');
+        var timeout = scripts[scripts.length - 1].getAttribute('data-timeout');
+        var success = function () {
+        };
+        var error = function (e) {
+            throw new Error('Configuration load failed : ' + e.message);
+        };
+        if (!key && !url) {
+            return;
+        }
+        var options = {
+            apiKey: key,
+            onSuccess: success,
+            onFailure: error
+        };
+        if (url) {
+            options.serverUrl = url;
+            options.callbackSuffix = '';
+        }
+        if (timeout) {
+            options.timeOut = timeout;
+        }
+        if (!Gp.Config) {
+            Gp.Services.getConfig(options);
+        }
+    }());
+}(gp);
+(function (window, document, undefined) {
+    L.drawVersion = '0.3.0-dev';
+    L.drawLocal = {
+        draw: {
+            toolbar: {
+                actions: {
+                    title: 'Cancel drawing',
+                    text: 'Cancel'
+                },
+                finish: {
+                    title: 'Finish drawing',
+                    text: 'Finish'
+                },
+                undo: {
+                    title: 'Delete last point drawn',
+                    text: 'Delete last point'
+                },
+                buttons: {
+                    polyline: 'Draw a polyline',
+                    polygon: 'Draw a polygon',
+                    rectangle: 'Draw a rectangle',
+                    circle: 'Draw a circle',
+                    marker: 'Draw a marker'
+                }
+            },
+            handlers: {
+                circle: {
+                    tooltip: { start: 'Click and drag to draw circle.' },
+                    radius: 'Radius'
+                },
+                marker: { tooltip: { start: 'Click map to place marker.' } },
+                polygon: {
+                    tooltip: {
+                        start: 'Click to start drawing shape.',
+                        cont: 'Click to continue drawing shape.',
+                        end: 'Click first point to close this shape.'
+                    }
+                },
+                polyline: {
+                    error: '<strong>Error:</strong> shape edges cannot cross!',
+                    tooltip: {
+                        start: 'Click to start drawing line.',
+                        cont: 'Click to continue drawing line.',
+                        end: 'Click last point to finish line.'
+                    }
+                },
+                rectangle: { tooltip: { start: 'Click and drag to draw rectangle.' } },
+                simpleshape: { tooltip: { end: 'Release mouse to finish drawing.' } }
+            }
+        },
+        edit: {
+            toolbar: {
+                actions: {
+                    save: {
+                        title: 'Save changes.',
+                        text: 'Save'
+                    },
+                    cancel: {
+                        title: 'Cancel editing, discards all changes.',
+                        text: 'Cancel'
+                    }
+                },
+                buttons: {
+                    edit: 'Edit layers.',
+                    editDisabled: 'No layers to edit.',
+                    remove: 'Delete layers.',
+                    removeDisabled: 'No layers to delete.'
+                }
+            },
+            handlers: {
+                edit: {
+                    tooltip: {
+                        text: 'Drag handles, or marker to edit feature.',
+                        subtext: 'Click cancel to undo changes.'
+                    }
+                },
+                remove: { tooltip: { text: 'Click on a feature to remove' } }
+            }
+        }
+    };
+    L.Draw = {};
+    L.Draw.Feature = L.Handler.extend({
+        includes: L.Mixin.Events,
+        initialize: function (map, options) {
+            this._map = map;
+            this._container = map._container;
+            this._overlayPane = map._panes.overlayPane;
+            this._popupPane = map._panes.popupPane;
+            if (options && options.shapeOptions) {
+                options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions);
+            }
+            L.setOptions(this, options);
+        },
+        enable: function () {
+            if (this._enabled) {
+                return;
+            }
+            L.Handler.prototype.enable.call(this);
+            this.fire('enabled', { handler: this.type });
+            this._map.fire('draw:drawstart', { layerType: this.type });
+        },
+        disable: function () {
+            if (!this._enabled) {
+                return;
+            }
+            L.Handler.prototype.disable.call(this);
+            this._map.fire('draw:drawstop', { layerType: this.type });
+            this.fire('disabled', { handler: this.type });
+        },
+        addHooks: function () {
+            var map = this._map;
+            if (map) {
+                L.DomUtil.disableTextSelection();
+                map.getContainer().focus();
+                this._tooltip = new L.Tooltip(this._map);
+                L.DomEvent.on(this._container, 'keyup', this._cancelDrawing, this);
+            }
+        },
+        removeHooks: function () {
+            if (this._map) {
+                L.DomUtil.enableTextSelection();
+                this._tooltip.dispose();
+                this._tooltip = null;
+                L.DomEvent.off(this._container, 'keyup', this._cancelDrawing, this);
+            }
+        },
+        setOptions: function (options) {
+            L.setOptions(this, options);
+        },
+        _fireCreatedEvent: function (layer) {
+            this._map.fire('draw:created', {
+                layer: layer,
+                layerType: this.type
+            });
+        },
+        _cancelDrawing: function (e) {
+            if (e.keyCode === 27) {
+                this.disable();
+            }
+        }
+    });
+    L.Draw.Polyline = L.Draw.Feature.extend({
+        statics: { TYPE: 'polyline' },
+        Poly: L.Polyline,
+        options: {
+            allowIntersection: true,
+            repeatMode: false,
+            drawError: {
+                color: '#b00b00',
+                timeout: 2500
+            },
+            icon: new L.DivIcon({
+                iconSize: new L.Point(8, 8),
+                className: 'leaflet-div-icon leaflet-editing-icon'
+            }),
+            touchIcon: new L.DivIcon({
+                iconSize: new L.Point(20, 20),
+                className: 'leaflet-div-icon leaflet-editing-icon leaflet-touch-icon'
+            }),
+            guidelineDistance: 20,
+            maxGuideLineLength: 4000,
+            shapeOptions: {
+                stroke: true,
+                color: '#f06eaa',
+                weight: 4,
+                opacity: 0.5,
+                fill: false,
+                clickable: true
+            },
+            metric: true,
+            feet: true,
+            showLength: true,
+            zIndexOffset: 2000
+        },
+        initialize: function (map, options) {
+            if (L.Browser.touch) {
+                this.options.icon = this.options.touchIcon;
+            }
+            this.options.drawError.message = L.drawLocal.draw.handlers.polyline.error;
+            if (options && options.drawError) {
+                options.drawError = L.Util.extend({}, this.options.drawError, options.drawError);
+            }
+            this.type = L.Draw.Polyline.TYPE;
+            L.Draw.Feature.prototype.initialize.call(this, map, options);
+        },
+        addHooks: function () {
+            L.Draw.Feature.prototype.addHooks.call(this);
+            if (this._map) {
+                this._markers = [];
+                this._markerGroup = new L.LayerGroup();
+                this._map.addLayer(this._markerGroup);
+                this._poly = new L.Polyline([], this.options.shapeOptions);
+                this._tooltip.updateContent(this._getTooltipText());
+                if (!this._mouseMarker) {
+                    this._mouseMarker = L.marker(this._map.getCenter(), {
+                        icon: L.divIcon({
+                            className: 'leaflet-mouse-marker',
+                            iconAnchor: [
+                                20,
+                                20
+                            ],
+                            iconSize: [
+                                40,
+                                40
+                            ]
+                        }),
+                        opacity: 0,
+                        zIndexOffset: this.options.zIndexOffset
+                    });
+                }
+                this._mouseMarker.on('mousedown', this._onMouseDown, this).on('mouseout', this._onMouseOut, this).on('mouseup', this._onMouseUp, this).on('mousemove', this._onMouseMove, this).addTo(this._map);
+                this._map.on('mouseup', this._onMouseUp, this).on('mousemove', this._onMouseMove, this).on('zoomlevelschange', this._onZoomEnd, this).on('click', this._onTouch, this).on('zoomend', this._onZoomEnd, this);
+            }
+        },
+        removeHooks: function () {
+            L.Draw.Feature.prototype.removeHooks.call(this);
+            this._clearHideErrorTimeout();
+            this._cleanUpShape();
+            this._map.removeLayer(this._markerGroup);
+            delete this._markerGroup;
+            delete this._markers;
+            this._map.removeLayer(this._poly);
+            delete this._poly;
+            this._mouseMarker.off('mousedown', this._onMouseDown, this).off('mouseout', this._onMouseOut, this).off('mouseup', this._onMouseUp, this).off('mousemove', this._onMouseMove, this);
+            this._map.removeLayer(this._mouseMarker);
+            delete this._mouseMarker;
+            this._clearGuides();
+            this._map.off('mouseup', this._onMouseUp, this).off('mousemove', this._onMouseMove, this).off('mouseup', this._onMouseUp, this).off('zoomend', this._onZoomEnd, this).off('click', this._onTouch, this);
+        },
+        deleteLastVertex: function () {
+            if (this._markers.length <= 1) {
+                return;
+            }
+            var lastMarker = this._markers.pop(), poly = this._poly, latlng = this._poly.spliceLatLngs(poly.getLatLngs().length - 1, 1)[0];
+            this._markerGroup.removeLayer(lastMarker);
+            if (poly.getLatLngs().length < 2) {
+                this._map.removeLayer(poly);
+            }
+            this._vertexChanged(latlng, false);
+        },
+        addVertex: function (latlng) {
+            var markersLength = this._markers.length;
+            if (markersLength > 0 && !this.options.allowIntersection && this._poly.newLatLngIntersects(latlng)) {
+                this._showErrorTooltip();
+                return;
+            } else if (this._errorShown) {
+                this._hideErrorTooltip();
+            }
+            this._markers.push(this._createMarker(latlng));
+            this._poly.addLatLng(latlng);
+            if (this._poly.getLatLngs().length === 2) {
+                this._map.addLayer(this._poly);
+            }
+            this._vertexChanged(latlng, true);
+        },
+        completeShape: function () {
+            if (this._markers.length <= 1) {
+                return;
+            }
+            this._fireCreatedEvent();
+            this.disable();
+            if (this.options.repeatMode) {
+                this.enable();
+            }
+        },
+        _finishShape: function () {
+            var intersects = this._poly.newLatLngIntersects(this._poly.getLatLngs()[0], true);
+            if (!this.options.allowIntersection && intersects || !this._shapeIsValid()) {
+                this._showErrorTooltip();
+                return;
+            }
+            this._fireCreatedEvent();
+            this.disable();
+            if (this.options.repeatMode) {
+                this.enable();
+            }
+        },
+        _shapeIsValid: function () {
+            return true;
+        },
+        _onZoomEnd: function () {
+            this._updateGuide();
+        },
+        _onMouseMove: function (e) {
+            var newPos = this._map.mouseEventToLayerPoint(e.originalEvent);
+            var latlng = this._map.layerPointToLatLng(newPos);
+            this._currentLatLng = latlng;
+            this._updateTooltip(latlng);
+            this._updateGuide(newPos);
+            this._mouseMarker.setLatLng(latlng);
+            L.DomEvent.preventDefault(e.originalEvent);
+        },
+        _vertexChanged: function (latlng, added) {
+            this._map.fire('draw:drawvertex', { layers: this._markerGroup });
+            this._updateFinishHandler();
+            this._updateRunningMeasure(latlng, added);
+            this._clearGuides();
+            this._updateTooltip();
+        },
+        _onMouseDown: function (e) {
+            var originalEvent = e.originalEvent;
+            this._mouseDownOrigin = L.point(originalEvent.clientX, originalEvent.clientY);
+        },
+        _onMouseUp: function (e) {
+            if (this._mouseDownOrigin) {
+                var distance = L.point(e.originalEvent.clientX, e.originalEvent.clientY).distanceTo(this._mouseDownOrigin);
+                if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) {
+                    this.addVertex(e.latlng);
+                }
+            }
+            this._mouseDownOrigin = null;
+        },
+        _onTouch: function (e) {
+            if (L.Browser.touch) {
+                this._onMouseDown(e);
+                this._onMouseUp(e);
+            }
+        },
+        _onMouseOut: function () {
+            if (this._tooltip) {
+                this._tooltip._onMouseOut.call(this._tooltip);
+            }
+        },
+        _updateFinishHandler: function () {
+            var markerCount = this._markers.length;
+            if (markerCount > 1) {
+                this._markers[markerCount - 1].on('click', this._finishShape, this);
+            }
+            if (markerCount > 2) {
+                this._markers[markerCount - 2].off('click', this._finishShape, this);
+            }
+        },
+        _createMarker: function (latlng) {
+            var marker = new L.Marker(latlng, {
+                icon: this.options.icon,
+                zIndexOffset: this.options.zIndexOffset * 2
+            });
+            this._markerGroup.addLayer(marker);
+            return marker;
+        },
+        _updateGuide: function (newPos) {
+            var markerCount = this._markers.length;
+            if (markerCount > 0) {
+                newPos = newPos || this._map.latLngToLayerPoint(this._currentLatLng);
+                this._clearGuides();
+                this._drawGuide(this._map.latLngToLayerPoint(this._markers[markerCount - 1].getLatLng()), newPos);
+            }
+        },
+        _updateTooltip: function (latLng) {
+            var text = this._getTooltipText();
+            if (latLng) {
+                this._tooltip.updatePosition(latLng);
+            }
+            if (!this._errorShown) {
+                this._tooltip.updateContent(text);
+            }
+        },
+        _drawGuide: function (pointA, pointB) {
+            var length = Math.floor(Math.sqrt(Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2))), guidelineDistance = this.options.guidelineDistance, maxGuideLineLength = this.options.maxGuideLineLength, i = length > maxGuideLineLength ? length - maxGuideLineLength : guidelineDistance, fraction, dashPoint, dash;
+            if (!this._guidesContainer) {
+                this._guidesContainer = L.DomUtil.create('div', 'leaflet-draw-guides', this._overlayPane);
+            }
+            for (; i < length; i += this.options.guidelineDistance) {
+                fraction = i / length;
+                dashPoint = {
+                    x: Math.floor(pointA.x * (1 - fraction) + fraction * pointB.x),
+                    y: Math.floor(pointA.y * (1 - fraction) + fraction * pointB.y)
+                };
+                dash = L.DomUtil.create('div', 'leaflet-draw-guide-dash', this._guidesContainer);
+                dash.style.backgroundColor = !this._errorShown ? this.options.shapeOptions.color : this.options.drawError.color;
+                L.DomUtil.setPosition(dash, dashPoint);
+            }
+        },
+        _updateGuideColor: function (color) {
+            if (this._guidesContainer) {
+                for (var i = 0, l = this._guidesContainer.childNodes.length; i < l; i++) {
+                    this._guidesContainer.childNodes[i].style.backgroundColor = color;
+                }
+            }
+        },
+        _clearGuides: function () {
+            if (this._guidesContainer) {
+                while (this._guidesContainer.firstChild) {
+                    this._guidesContainer.removeChild(this._guidesContainer.firstChild);
+                }
+            }
+        },
+        _getTooltipText: function () {
+            var showLength = this.options.showLength, labelText, distanceStr;
+            if (this._markers.length === 0) {
+                labelText = { text: L.drawLocal.draw.handlers.polyline.tooltip.start };
+            } else {
+                distanceStr = showLength ? this._getMeasurementString() : '';
+                if (this._markers.length === 1) {
+                    labelText = {
+                        text: L.drawLocal.draw.handlers.polyline.tooltip.cont,
+                        subtext: distanceStr
+                    };
+                } else {
+                    labelText = {
+                        text: L.drawLocal.draw.handlers.polyline.tooltip.end,
+                        subtext: distanceStr
+                    };
+                }
+            }
+            return labelText;
+        },
+        _updateRunningMeasure: function (latlng, added) {
+            var markersLength = this._markers.length, previousMarkerIndex, distance;
+            if (this._markers.length === 1) {
+                this._measurementRunningTotal = 0;
+            } else {
+                previousMarkerIndex = markersLength - (added ? 2 : 1);
+                distance = latlng.distanceTo(this._markers[previousMarkerIndex].getLatLng());
+                this._measurementRunningTotal += distance * (added ? 1 : -1);
+            }
+        },
+        _getMeasurementString: function () {
+            var currentLatLng = this._currentLatLng, previousLatLng = this._markers[this._markers.length - 1].getLatLng(), distance;
+            distance = this._measurementRunningTotal + currentLatLng.distanceTo(previousLatLng);
+            return L.GeometryUtil.readableDistance(distance, this.options.metric, this.options.feet);
+        },
+        _showErrorTooltip: function () {
+            this._errorShown = true;
+            this._tooltip.showAsError().updateContent({ text: this.options.drawError.message });
+            this._updateGuideColor(this.options.drawError.color);
+            this._poly.setStyle({ color: this.options.drawError.color });
+            this._clearHideErrorTimeout();
+            this._hideErrorTimeout = setTimeout(L.Util.bind(this._hideErrorTooltip, this), this.options.drawError.timeout);
+        },
+        _hideErrorTooltip: function () {
+            this._errorShown = false;
+            this._clearHideErrorTimeout();
+            this._tooltip.removeError().updateContent(this._getTooltipText());
+            this._updateGuideColor(this.options.shapeOptions.color);
+            this._poly.setStyle({ color: this.options.shapeOptions.color });
+        },
+        _clearHideErrorTimeout: function () {
+            if (this._hideErrorTimeout) {
+                clearTimeout(this._hideErrorTimeout);
+                this._hideErrorTimeout = null;
+            }
+        },
+        _cleanUpShape: function () {
+            if (this._markers.length > 1) {
+                this._markers[this._markers.length - 1].off('click', this._finishShape, this);
+            }
+        },
+        _fireCreatedEvent: function () {
+            var poly = new this.Poly(this._poly.getLatLngs(), this.options.shapeOptions);
+            L.Draw.Feature.prototype._fireCreatedEvent.call(this, poly);
+        }
+    });
+    L.Draw.Polygon = L.Draw.Polyline.extend({
+        statics: { TYPE: 'polygon' },
+        Poly: L.Polygon,
+        options: {
+            showArea: false,
+            shapeOptions: {
+                stroke: true,
+                color: '#f06eaa',
+                weight: 4,
+                opacity: 0.5,
+                fill: true,
+                fillColor: null,
+                fillOpacity: 0.2,
+                clickable: true
+            }
+        },
+        initialize: function (map, options) {
+            L.Draw.Polyline.prototype.initialize.call(this, map, options);
+            this.type = L.Draw.Polygon.TYPE;
+        },
+        _updateFinishHandler: function () {
+            var markerCount = this._markers.length;
+            if (markerCount === 1) {
+                this._markers[0].on('click', this._finishShape, this);
+            }
+            if (markerCount > 2) {
+                this._markers[markerCount - 1].on('dblclick', this._finishShape, this);
+                if (markerCount > 3) {
+                    this._markers[markerCount - 2].off('dblclick', this._finishShape, this);
+                }
+            }
+        },
+        _getTooltipText: function () {
+            var text, subtext;
+            if (this._markers.length === 0) {
+                text = L.drawLocal.draw.handlers.polygon.tooltip.start;
+            } else if (this._markers.length < 3) {
+                text = L.drawLocal.draw.handlers.polygon.tooltip.cont;
+            } else {
+                text = L.drawLocal.draw.handlers.polygon.tooltip.end;
+                subtext = this._getMeasurementString();
+            }
+            return {
+                text: text,
+                subtext: subtext
+            };
+        },
+        _getMeasurementString: function () {
+            var area = this._area;
+            if (!area) {
+                return null;
+            }
+            return L.GeometryUtil.readableArea(area, this.options.metric);
+        },
+        _shapeIsValid: function () {
+            return this._markers.length >= 3;
+        },
+        _vertexChanged: function (latlng, added) {
+            var latLngs;
+            if (!this.options.allowIntersection && this.options.showArea) {
+                latLngs = this._poly.getLatLngs();
+                this._area = L.GeometryUtil.geodesicArea(latLngs);
+            }
+            L.Draw.Polyline.prototype._vertexChanged.call(this, latlng, added);
+        },
+        _cleanUpShape: function () {
+            var markerCount = this._markers.length;
+            if (markerCount > 0) {
+                this._markers[0].off('click', this._finishShape, this);
+                if (markerCount > 2) {
+                    this._markers[markerCount - 1].off('dblclick', this._finishShape, this);
+                }
+            }
+        }
+    });
+    L.SimpleShape = {};
+    L.Draw.SimpleShape = L.Draw.Feature.extend({
+        options: { repeatMode: false },
+        initialize: function (map, options) {
+            this._endLabelText = L.drawLocal.draw.handlers.simpleshape.tooltip.end;
+            L.Draw.Feature.prototype.initialize.call(this, map, options);
+        },
+        addHooks: function () {
+            L.Draw.Feature.prototype.addHooks.call(this);
+            if (this._map) {
+                this._mapDraggable = this._map.dragging.enabled();
+                if (this._mapDraggable) {
+                    this._map.dragging.disable();
+                }
+                this._container.style.cursor = 'crosshair';
+                this._tooltip.updateContent({ text: this._initialLabelText });
+                this._map.on('mousedown', this._onMouseDown, this).on('mousemove', this._onMouseMove, this).on('touchstart', this._onMouseDown, this).on('touchmove', this._onMouseMove, this);
+            }
+        },
+        removeHooks: function () {
+            L.Draw.Feature.prototype.removeHooks.call(this);
+            if (this._map) {
+                if (this._mapDraggable) {
+                    this._map.dragging.enable();
+                }
+                this._container.style.cursor = '';
+                this._map.off('mousedown', this._onMouseDown, this).off('mousemove', this._onMouseMove, this).off('touchstart', this._onMouseDown, this).off('touchmove', this._onMouseMove, this);
+                L.DomEvent.off(document, 'mouseup', this._onMouseUp, this);
+                L.DomEvent.off(document, 'touchend', this._onMouseUp, this);
+                if (this._shape) {
+                    this._map.removeLayer(this._shape);
+                    delete this._shape;
+                }
+            }
+            this._isDrawing = false;
+        },
+        _getTooltipText: function () {
+            return { text: this._endLabelText };
+        },
+        _onMouseDown: function (e) {
+            this._isDrawing = true;
+            this._startLatLng = e.latlng;
+            L.DomEvent.on(document, 'mouseup', this._onMouseUp, this).on(document, 'touchend', this._onMouseUp, this).preventDefault(e.originalEvent);
+        },
+        _onMouseMove: function (e) {
+            var latlng = e.latlng;
+            this._tooltip.updatePosition(latlng);
+            if (this._isDrawing) {
+                this._tooltip.updateContent(this._getTooltipText());
+                this._drawShape(latlng);
+            }
+        },
+        _onMouseUp: function () {
+            if (this._shape) {
+                this._fireCreatedEvent();
+            }
+            this.disable();
+            if (this.options.repeatMode) {
+                this.enable();
+            }
+        }
+    });
+    L.Draw.Rectangle = L.Draw.SimpleShape.extend({
+        statics: { TYPE: 'rectangle' },
+        options: {
+            shapeOptions: {
+                stroke: true,
+                color: '#f06eaa',
+                weight: 4,
+                opacity: 0.5,
+                fill: true,
+                fillColor: null,
+                fillOpacity: 0.2,
+                clickable: true
+            },
+            metric: true
+        },
+        initialize: function (map, options) {
+            this.type = L.Draw.Rectangle.TYPE;
+            this._initialLabelText = L.drawLocal.draw.handlers.rectangle.tooltip.start;
+            L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
+        },
+        _drawShape: function (latlng) {
+            if (!this._shape) {
+                this._shape = new L.Rectangle(new L.LatLngBounds(this._startLatLng, latlng), this.options.shapeOptions);
+                this._map.addLayer(this._shape);
+            } else {
+                this._shape.setBounds(new L.LatLngBounds(this._startLatLng, latlng));
+            }
+        },
+        _fireCreatedEvent: function () {
+            var rectangle = new L.Rectangle(this._shape.getBounds(), this.options.shapeOptions);
+            L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, rectangle);
+        },
+        _getTooltipText: function () {
+            var tooltipText = L.Draw.SimpleShape.prototype._getTooltipText.call(this), shape = this._shape, latLngs, area, subtext;
+            if (shape) {
+                latLngs = this._shape.getLatLngs();
+                area = L.GeometryUtil.geodesicArea(latLngs);
+                subtext = L.GeometryUtil.readableArea(area, this.options.metric);
+            }
+            return {
+                text: tooltipText.text,
+                subtext: subtext
+            };
+        }
+    });
+    L.Draw.Circle = L.Draw.SimpleShape.extend({
+        statics: { TYPE: 'circle' },
+        options: {
+            shapeOptions: {
+                stroke: true,
+                color: '#f06eaa',
+                weight: 4,
+                opacity: 0.5,
+                fill: true,
+                fillColor: null,
+                fillOpacity: 0.2,
+                clickable: true
+            },
+            showRadius: true,
+            metric: true,
+            feet: true
+        },
+        initialize: function (map, options) {
+            this.type = L.Draw.Circle.TYPE;
+            this._initialLabelText = L.drawLocal.draw.handlers.circle.tooltip.start;
+            L.Draw.SimpleShape.prototype.initialize.call(this, map, options);
+        },
+        _drawShape: function (latlng) {
+            if (!this._shape) {
+                this._shape = new L.Circle(this._startLatLng, this._startLatLng.distanceTo(latlng), this.options.shapeOptions);
+                this._map.addLayer(this._shape);
+            } else {
+                this._shape.setRadius(this._startLatLng.distanceTo(latlng));
+            }
+        },
+        _fireCreatedEvent: function () {
+            var circle = new L.Circle(this._startLatLng, this._shape.getRadius(), this.options.shapeOptions);
+            L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, circle);
+        },
+        _onMouseMove: function (e) {
+            var latlng = e.latlng, showRadius = this.options.showRadius, useMetric = this.options.metric, radius;
+            this._tooltip.updatePosition(latlng);
+            if (this._isDrawing) {
+                this._drawShape(latlng);
+                radius = this._shape.getRadius().toFixed(1);
+                this._tooltip.updateContent({
+                    text: this._endLabelText,
+                    subtext: showRadius ? L.drawLocal.draw.handlers.circle.radius + ': ' + L.GeometryUtil.readableDistance(radius, useMetric, this.options.feet) : ''
+                });
+            }
+        }
+    });
+    L.Draw.Marker = L.Draw.Feature.extend({
+        statics: { TYPE: 'marker' },
+        options: {
+            icon: new L.Icon.Default(),
+            repeatMode: false,
+            zIndexOffset: 2000
+        },
+        initialize: function (map, options) {
+            this.type = L.Draw.Marker.TYPE;
+            L.Draw.Feature.prototype.initialize.call(this, map, options);
+        },
+        addHooks: function () {
+            L.Draw.Feature.prototype.addHooks.call(this);
+            if (this._map) {
+                this._tooltip.updateContent({ text: L.drawLocal.draw.handlers.marker.tooltip.start });
+                if (!this._mouseMarker) {
+                    this._mouseMarker = L.marker(this._map.getCenter(), {
+                        icon: L.divIcon({
+                            className: 'leaflet-mouse-marker',
+                            iconAnchor: [
+                                20,
+                                20
+                            ],
+                            iconSize: [
+                                40,
+                                40
+                            ]
+                        }),
+                        opacity: 0,
+                        zIndexOffset: this.options.zIndexOffset
+                    });
+                }
+                this._mouseMarker.on('click', this._onClick, this).addTo(this._map);
+                this._map.on('mousemove', this._onMouseMove, this);
+                this._map.on('click', this._onTouch, this);
+            }
+        },
+        removeHooks: function () {
+            L.Draw.Feature.prototype.removeHooks.call(this);
+            if (this._map) {
+                if (this._marker) {
+                    this._marker.off('click', this._onClick, this);
+                    this._map.off('click', this._onClick, this).off('click', this._onTouch, this).removeLayer(this._marker);
+                    delete this._marker;
+                }
+                this._mouseMarker.off('click', this._onClick, this);
+                this._map.removeLayer(this._mouseMarker);
+                delete this._mouseMarker;
+                this._map.off('mousemove', this._onMouseMove, this);
+            }
+        },
+        _onMouseMove: function (e) {
+            var latlng = e.latlng;
+            this._tooltip.updatePosition(latlng);
+            this._mouseMarker.setLatLng(latlng);
+            if (!this._marker) {
+                this._marker = new L.Marker(latlng, {
+                    icon: this.options.icon,
+                    zIndexOffset: this.options.zIndexOffset
+                });
+                this._marker.on('click', this._onClick, this);
+                this._map.on('click', this._onClick, this).addLayer(this._marker);
+            } else {
+                latlng = this._mouseMarker.getLatLng();
+                this._marker.setLatLng(latlng);
+            }
+        },
+        _onClick: function () {
+            this._fireCreatedEvent();
+            this.disable();
+            if (this.options.repeatMode) {
+                this.enable();
+            }
+        },
+        _onTouch: function (e) {
+            this._onMouseMove(e);
+            this._onClick();
+        },
+        _fireCreatedEvent: function () {
+            var marker = new L.Marker.Touch(this._marker.getLatLng(), { icon: this.options.icon });
+            L.Draw.Feature.prototype._fireCreatedEvent.call(this, marker);
+        }
+    });
+    L.Edit = L.Edit || {};
+    L.Edit.Marker = L.Handler.extend({
+        initialize: function (marker, options) {
+            this._marker = marker;
+            L.setOptions(this, options);
+        },
+        addHooks: function () {
+            var marker = this._marker;
+            marker.dragging.enable();
+            marker.on('dragend', this._onDragEnd, marker);
+            this._toggleMarkerHighlight();
+        },
+        removeHooks: function () {
+            var marker = this._marker;
+            marker.dragging.disable();
+            marker.off('dragend', this._onDragEnd, marker);
+            this._toggleMarkerHighlight();
+        },
+        _onDragEnd: function (e) {
+            var layer = e.target;
+            layer.edited = true;
+        },
+        _toggleMarkerHighlight: function () {
+            var icon = this._marker._icon;
+            if (!icon) {
+                return;
+            }
+            icon.style.display = 'none';
+            if (L.DomUtil.hasClass(icon, 'leaflet-edit-marker-selected')) {
+                L.DomUtil.removeClass(icon, 'leaflet-edit-marker-selected');
+                this._offsetMarker(icon, -4);
+            } else {
+                L.DomUtil.addClass(icon, 'leaflet-edit-marker-selected');
+                this._offsetMarker(icon, 4);
+            }
+            icon.style.display = '';
+        },
+        _offsetMarker: function (icon, offset) {
+            var iconMarginTop = parseInt(icon.style.marginTop, 10) - offset, iconMarginLeft = parseInt(icon.style.marginLeft, 10) - offset;
+            icon.style.marginTop = iconMarginTop + 'px';
+            icon.style.marginLeft = iconMarginLeft + 'px';
+        }
+    });
+    L.Marker.addInitHook(function () {
+        if (L.Edit.Marker) {
+            this.editing = new L.Edit.Marker(this);
+            if (this.options.editable) {
+                this.editing.enable();
+            }
+        }
+    });
+    L.Edit = L.Edit || {};
+    L.Edit.Poly = L.Handler.extend({
+        options: {},
+        initialize: function (poly, options) {
+            this.latlngs = [poly._latlngs];
+            if (poly._holes) {
+                this.latlngs = this.latlngs.concat(poly._holes);
+            }
+            this._verticesHandlers = [];
+            for (var i = 0; i < this.latlngs.length; i++) {
+                this._verticesHandlers.push(new L.Edit.PolyVerticesEdit(poly, this.latlngs[i], options));
+            }
+            this._poly = poly;
+            L.setOptions(this, options);
+        },
+        _eachVertexHandler: function (callback) {
+            for (var i = 0; i < this._verticesHandlers.length; i++) {
+                callback(this._verticesHandlers[i]);
+            }
+        },
+        addHooks: function () {
+            this._eachVertexHandler(function (handler) {
+                handler.addHooks();
+            });
+        },
+        removeHooks: function () {
+            this._eachVertexHandler(function (handler) {
+                handler.removeHooks();
+            });
+        },
+        updateMarkers: function () {
+            this._eachVertexHandler(function (handler) {
+                handler.updateMarkers();
+            });
+        }
+    });
+    L.Edit.PolyVerticesEdit = L.Handler.extend({
+        options: {
+            icon: new L.DivIcon({
+                iconSize: new L.Point(8, 8),
+                className: 'leaflet-div-icon leaflet-editing-icon'
+            }),
+            touchIcon: new L.DivIcon({
+                iconSize: new L.Point(20, 20),
+                className: 'leaflet-div-icon leaflet-editing-icon leaflet-touch-icon'
+            })
+        },
+        initialize: function (poly, latlngs, options) {
+            if (L.Browser.touch) {
+                this.options.icon = this.options.touchIcon;
+            }
+            this._poly = poly;
+            this._latlngs = latlngs;
+            L.setOptions(this, options);
+        },
+        addHooks: function () {
+            var poly = this._poly;
+            if (!(poly instanceof L.Polygon)) {
+                poly.options.editing.fill = false;
+            }
+            poly.setStyle(poly.options.editing);
+            if (this._poly._map) {
+                this._map = this._poly._map;
+                if (!this._markerGroup) {
+                    this._initMarkers();
+                }
+                this._poly._map.addLayer(this._markerGroup);
+            }
+        },
+        removeHooks: function () {
+            var poly = this._poly;
+            poly.setStyle(poly.options.original);
+            if (poly._map) {
+                poly._map.removeLayer(this._markerGroup);
+                delete this._markerGroup;
+                delete this._markers;
+            }
+        },
+        updateMarkers: function () {
+            this._markerGroup.clearLayers();
+            this._initMarkers();
+        },
+        _initMarkers: function () {
+            if (!this._markerGroup) {
+                this._markerGroup = new L.LayerGroup();
+            }
+            this._markers = [];
+            var latlngs = this._latlngs, i, j, len, marker;
+            for (i = 0, len = latlngs.length; i < len; i++) {
+                marker = this._createMarker(latlngs[i], i);
+                marker.on('click', this._onMarkerClick, this);
+                this._markers.push(marker);
+            }
+            var markerLeft, markerRight;
+            for (i = 0, j = len - 1; i < len; j = i++) {
+                if (i === 0 && !(L.Polygon && this._poly instanceof L.Polygon)) {
+                    continue;
+                }
+                markerLeft = this._markers[j];
+                markerRight = this._markers[i];
+                this._createMiddleMarker(markerLeft, markerRight);
+                this._updatePrevNext(markerLeft, markerRight);
+            }
+        },
+        _createMarker: function (latlng, index) {
+            var marker = new L.Marker.Touch(latlng, {
+                draggable: true,
+                icon: this.options.icon
+            });
+            marker._origLatLng = latlng;
+            marker._index = index;
+            marker.on('dragstart', this._onMarkerDragStart, this).on('drag', this._onMarkerDrag, this).on('dragend', this._fireEdit, this).on('touchmove', this._onTouchMove, this).on('MSPointerMove', this._onTouchMove, this).on('touchend', this._fireEdit, this).on('MSPointerUp', this._fireEdit, this);
+            this._markerGroup.addLayer(marker);
+            return marker;
+        },
+        _onMarkerDragStart: function () {
+            this._poly.fire('editstart');
+        },
+        _spliceLatLngs: function () {
+            var removed = [].splice.apply(this._latlngs, arguments);
+            this._poly._convertLatLngs(this._latlngs, true);
+            this._poly.redraw();
+            return removed;
+        },
+        _removeMarker: function (marker) {
+            var i = marker._index;
+            this._markerGroup.removeLayer(marker);
+            this._markers.splice(i, 1);
+            this._spliceLatLngs(i, 1);
+            this._updateIndexes(i, -1);
+            marker.off('dragstart', this._onMarkerDragStart, this).off('drag', this._onMarkerDrag, this).off('dragend', this._fireEdit, this).off('touchmove', this._onMarkerDrag, this).off('touchend', this._fireEdit, this).off('click', this._onMarkerClick, this);
+        },
+        _fireEdit: function () {
+            this._poly.edited = true;
+            this._poly.fire('edit');
+            this._poly._map.fire('draw:editvertex', { layers: this._markerGroup });
+        },
+        _onMarkerDrag: function (e) {
+            var marker = e.target;
+            L.extend(marker._origLatLng, marker._latlng);
+            if (marker._middleLeft) {
+                marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
+            }
+            if (marker._middleRight) {
+                marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
+            }
+            this._poly.redraw();
+            this._poly.fire('editdrag');
+        },
+        _onMarkerClick: function (e) {
+            var minPoints = L.Polygon && this._poly instanceof L.Polygon ? 4 : 3, marker = e.target;
+            if (this._latlngs.length < minPoints) {
+                return;
+            }
+            this._removeMarker(marker);
+            this._updatePrevNext(marker._prev, marker._next);
+            if (marker._middleLeft) {
+                this._markerGroup.removeLayer(marker._middleLeft);
+            }
+            if (marker._middleRight) {
+                this._markerGroup.removeLayer(marker._middleRight);
+            }
+            if (marker._prev && marker._next) {
+                this._createMiddleMarker(marker._prev, marker._next);
+            } else if (!marker._prev) {
+                marker._next._middleLeft = null;
+            } else if (!marker._next) {
+                marker._prev._middleRight = null;
+            }
+            this._fireEdit();
+        },
+        _onTouchMove: function (e) {
+            var layerPoint = this._map.mouseEventToLayerPoint(e.originalEvent.touches[0]), latlng = this._map.layerPointToLatLng(layerPoint), marker = e.target;
+            L.extend(marker._origLatLng, latlng);
+            if (marker._middleLeft) {
+                marker._middleLeft.setLatLng(this._getMiddleLatLng(marker._prev, marker));
+            }
+            if (marker._middleRight) {
+                marker._middleRight.setLatLng(this._getMiddleLatLng(marker, marker._next));
+            }
+            this._poly.redraw();
+            this.updateMarkers();
+        },
+        _updateIndexes: function (index, delta) {
+            this._markerGroup.eachLayer(function (marker) {
+                if (marker._index > index) {
+                    marker._index += delta;
+                }
+            });
+        },
+        _createMiddleMarker: function (marker1, marker2) {
+            var latlng = this._getMiddleLatLng(marker1, marker2), marker = this._createMarker(latlng), onClick, onDragStart, onDragEnd;
+            marker.setOpacity(0.6);
+            marker1._middleRight = marker2._middleLeft = marker;
+            onDragStart = function () {
+                var i = marker2._index;
+                marker._index = i;
+                marker.off('click', onClick, this).on('click', this._onMarkerClick, this);
+                latlng.lat = marker.getLatLng().lat;
+                latlng.lng = marker.getLatLng().lng;
+                this._spliceLatLngs(i, 0, latlng);
+                this._markers.splice(i, 0, marker);
+                marker.setOpacity(1);
+                this._updateIndexes(i, 1);
+                marker2._index++;
+                this._updatePrevNext(marker1, marker);
+                this._updatePrevNext(marker, marker2);
+                this._poly.fire('editstart');
+            };
+            onDragEnd = function () {
+                marker.off('dragstart', onDragStart, this);
+                marker.off('dragend', onDragEnd, this);
+                marker.off('touchmove', onDragStart, this);
+                this._createMiddleMarker(marker1, marker);
+                this._createMiddleMarker(marker, marker2);
+            };
+            onClick = function () {
+                onDragStart.call(this);
+                onDragEnd.call(this);
+                this._fireEdit();
+            };
+            marker.on('click', onClick, this).on('dragstart', onDragStart, this).on('dragend', onDragEnd, this).on('touchmove', onDragStart, this);
+            this._markerGroup.addLayer(marker);
+        },
+        _updatePrevNext: function (marker1, marker2) {
+            if (marker1) {
+                marker1._next = marker2;
+            }
+            if (marker2) {
+                marker2._prev = marker1;
+            }
+        },
+        _getMiddleLatLng: function (marker1, marker2) {
+            var map = this._poly._map, p1 = map.project(marker1.getLatLng()), p2 = map.project(marker2.getLatLng());
+            return map.unproject(p1._add(p2)._divideBy(2));
+        }
+    });
+    L.Polyline.addInitHook(function () {
+        if (this.editing) {
+            return;
+        }
+        if (L.Edit.Poly) {
+            this.editing = new L.Edit.Poly(this);
+            if (this.options.editable) {
+                this.editing.enable();
+            }
+        }
+        this.on('add', function () {
+            if (this.editing && this.editing.enabled()) {
+                this.editing.addHooks();
+            }
+        });
+        this.on('remove', function () {
+            if (this.editing && this.editing.enabled()) {
+                this.editing.removeHooks();
+            }
+        });
+    });
+    L.Edit = L.Edit || {};
+    L.Edit.SimpleShape = L.Handler.extend({
+        options: {
+            moveIcon: new L.DivIcon({
+                iconSize: new L.Point(8, 8),
+                className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move'
+            }),
+            resizeIcon: new L.DivIcon({
+                iconSize: new L.Point(8, 8),
+                className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize'
+            }),
+            touchMoveIcon: new L.DivIcon({
+                iconSize: new L.Point(20, 20),
+                className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-move leaflet-touch-icon'
+            }),
+            touchResizeIcon: new L.DivIcon({
+                iconSize: new L.Point(20, 20),
+                className: 'leaflet-div-icon leaflet-editing-icon leaflet-edit-resize leaflet-touch-icon'
+            })
+        },
+        initialize: function (shape, options) {
+            if (L.Browser.touch) {
+                this.options.moveIcon = this.options.touchMoveIcon;
+                this.options.resizeIcon = this.options.touchResizeIcon;
+            }
+            this._shape = shape;
+            L.Util.setOptions(this, options);
+        },
+        addHooks: function () {
+            var shape = this._shape;
+            if (this._shape._map) {
+                this._map = this._shape._map;
+                shape.setStyle(shape.options.editing);
+                if (shape._map) {
+                    this._map = shape._map;
+                    if (!this._markerGroup) {
+                        this._initMarkers();
+                    }
+                    this._map.addLayer(this._markerGroup);
+                }
+            }
+        },
+        removeHooks: function () {
+            var shape = this._shape;
+            shape.setStyle(shape.options.original);
+            if (shape._map) {
+                this._unbindMarker(this._moveMarker);
+                for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
+                    this._unbindMarker(this._resizeMarkers[i]);
+                }
+                this._resizeMarkers = null;
+                this._map.removeLayer(this._markerGroup);
+                delete this._markerGroup;
+            }
+            this._map = null;
+        },
+        updateMarkers: function () {
+            this._markerGroup.clearLayers();
+            this._initMarkers();
+        },
+        _initMarkers: function () {
+            if (!this._markerGroup) {
+                this._markerGroup = new L.LayerGroup();
+            }
+            this._createMoveMarker();
+            this._createResizeMarker();
+        },
+        _createMoveMarker: function () {
+        },
+        _createResizeMarker: function () {
+        },
+        _createMarker: function (latlng, icon) {
+            var marker = new L.Marker.Touch(latlng, {
+                draggable: true,
+                icon: icon,
+                zIndexOffset: 10
+            });
+            this._bindMarker(marker);
+            this._markerGroup.addLayer(marker);
+            return marker;
+        },
+        _bindMarker: function (marker) {
+            marker.on('dragstart', this._onMarkerDragStart, this).on('drag', this._onMarkerDrag, this).on('dragend', this._onMarkerDragEnd, this).on('touchstart', this._onTouchStart, this).on('touchmove', this._onTouchMove, this).on('MSPointerMove', this._onTouchMove, this).on('touchend', this._onTouchEnd, this).on('MSPointerUp', this._onTouchEnd, this);
+        },
+        _unbindMarker: function (marker) {
+            marker.off('dragstart', this._onMarkerDragStart, this).off('drag', this._onMarkerDrag, this).off('dragend', this._onMarkerDragEnd, this).off('touchstart', this._onTouchStart, this).off('touchmove', this._onTouchMove, this).off('MSPointerMove', this._onTouchMove, this).off('touchend', this._onTouchEnd, this).off('MSPointerUp', this._onTouchEnd, this);
+        },
+        _onMarkerDragStart: function (e) {
+            var marker = e.target;
+            marker.setOpacity(0);
+            this._shape.fire('editstart');
+        },
+        _fireEdit: function () {
+            this._shape.edited = true;
+            this._shape.fire('edit');
+        },
+        _onMarkerDrag: function (e) {
+            var marker = e.target, latlng = marker.getLatLng();
+            if (marker === this._moveMarker) {
+                this._move(latlng);
+            } else {
+                this._resize(latlng);
+            }
+            this._shape.redraw();
+            this._shape.fire('editdrag');
+        },
+        _onMarkerDragEnd: function (e) {
+            var marker = e.target;
+            marker.setOpacity(1);
+            this._fireEdit();
+        },
+        _onTouchStart: function (e) {
+            L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e);
+            if (typeof this._getCorners === 'function') {
+                var corners = this._getCorners(), marker = e.target, currentCornerIndex = marker._cornerIndex;
+                marker.setOpacity(0);
+                this._oppositeCorner = corners[(currentCornerIndex + 2) % 4];
+                this._toggleCornerMarkers(0, currentCornerIndex);
+            }
+            this._shape.fire('editstart');
+        },
+        _onTouchMove: function (e) {
+            var layerPoint = this._map.mouseEventToLayerPoint(e.originalEvent.touches[0]), latlng = this._map.layerPointToLatLng(layerPoint), marker = e.target;
+            if (marker === this._moveMarker) {
+                this._move(latlng);
+            } else {
+                this._resize(latlng);
+            }
+            this._shape.redraw();
+            return false;
+        },
+        _onTouchEnd: function (e) {
+            var marker = e.target;
+            marker.setOpacity(1);
+            this.updateMarkers();
+            this._fireEdit();
+        },
+        _move: function () {
+        },
+        _resize: function () {
+        }
+    });
+    L.Edit = L.Edit || {};
+    L.Edit.Rectangle = L.Edit.SimpleShape.extend({
+        _createMoveMarker: function () {
+            var bounds = this._shape.getBounds(), center = bounds.getCenter();
+            this._moveMarker = this._createMarker(center, this.options.moveIcon);
+        },
+        _createResizeMarker: function () {
+            var corners = this._getCorners();
+            this._resizeMarkers = [];
+            for (var i = 0, l = corners.length; i < l; i++) {
+                this._resizeMarkers.push(this._createMarker(corners[i], this.options.resizeIcon));
+                this._resizeMarkers[i]._cornerIndex = i;
+            }
+        },
+        _onMarkerDragStart: function (e) {
+            L.Edit.SimpleShape.prototype._onMarkerDragStart.call(this, e);
+            var corners = this._getCorners(), marker = e.target, currentCornerIndex = marker._cornerIndex;
+            this._oppositeCorner = corners[(currentCornerIndex + 2) % 4];
+            this._toggleCornerMarkers(0, currentCornerIndex);
+        },
+        _onMarkerDragEnd: function (e) {
+            var marker = e.target, bounds, center;
+            if (marker === this._moveMarker) {
+                bounds = this._shape.getBounds();
+                center = bounds.getCenter();
+                marker.setLatLng(center);
+            }
+            this._toggleCornerMarkers(1);
+            this._repositionCornerMarkers();
+            L.Edit.SimpleShape.prototype._onMarkerDragEnd.call(this, e);
+        },
+        _move: function (newCenter) {
+            var latlngs = this._shape.getLatLngs(), bounds = this._shape.getBounds(), center = bounds.getCenter(), offset, newLatLngs = [];
+            for (var i = 0, l = latlngs.length; i < l; i++) {
+                offset = [
+                    latlngs[i].lat - center.lat,
+                    latlngs[i].lng - center.lng
+                ];
+                newLatLngs.push([
+                    newCenter.lat + offset[0],
+                    newCenter.lng + offset[1]
+                ]);
+            }
+            this._shape.setLatLngs(newLatLngs);
+            this._repositionCornerMarkers();
+        },
+        _resize: function (latlng) {
+            var bounds;
+            this._shape.setBounds(L.latLngBounds(latlng, this._oppositeCorner));
+            bounds = this._shape.getBounds();
+            this._moveMarker.setLatLng(bounds.getCenter());
+        },
+        _getCorners: function () {
+            var bounds = this._shape.getBounds(), nw = bounds.getNorthWest(), ne = bounds.getNorthEast(), se = bounds.getSouthEast(), sw = bounds.getSouthWest();
+            return [
+                nw,
+                ne,
+                se,
+                sw
+            ];
+        },
+        _toggleCornerMarkers: function (opacity) {
+            for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
+                this._resizeMarkers[i].setOpacity(opacity);
+            }
+        },
+        _repositionCornerMarkers: function () {
+            var corners = this._getCorners();
+            for (var i = 0, l = this._resizeMarkers.length; i < l; i++) {
+                this._resizeMarkers[i].setLatLng(corners[i]);
+            }
+        }
+    });
+    L.Rectangle.addInitHook(function () {
+        if (L.Edit.Rectangle) {
+            this.editing = new L.Edit.Rectangle(this);
+            if (this.options.editable) {
+                this.editing.enable();
+            }
+        }
+    });
+    L.Edit = L.Edit || {};
+    L.Edit.Circle = L.Edit.SimpleShape.extend({
+        _createMoveMarker: function () {
+            var center = this._shape.getLatLng();
+            this._moveMarker = this._createMarker(center, this.options.moveIcon);
+        },
+        _createResizeMarker: function () {
+            var center = this._shape.getLatLng(), resizemarkerPoint = this._getResizeMarkerPoint(center);
+            this._resizeMarkers = [];
+            this._resizeMarkers.push(this._createMarker(resizemarkerPoint, this.options.resizeIcon));
+        },
+        _getResizeMarkerPoint: function (latlng) {
+            var delta = this._shape._radius * Math.cos(Math.PI / 4), point = this._map.project(latlng);
+            return this._map.unproject([
+                point.x + delta,
+                point.y - delta
+            ]);
+        },
+        _move: function (latlng) {
+            var resizemarkerPoint = this._getResizeMarkerPoint(latlng);
+            this._resizeMarkers[0].setLatLng(resizemarkerPoint);
+            this._shape.setLatLng(latlng);
+        },
+        _resize: function (latlng) {
+            var moveLatLng = this._moveMarker.getLatLng(), radius = moveLatLng.distanceTo(latlng);
+            this._shape.setRadius(radius);
+        }
+    });
+    L.Circle.addInitHook(function () {
+        if (L.Edit.Circle) {
+            this.editing = new L.Edit.Circle(this);
+            if (this.options.editable) {
+                this.editing.enable();
+            }
+        }
+        this.on('add', function () {
+            if (this.editing && this.editing.enabled()) {
+                this.editing.addHooks();
+            }
+        });
+        this.on('remove', function () {
+            if (this.editing && this.editing.enabled()) {
+                this.editing.removeHooks();
+            }
+        });
+    });
+    L.Map.mergeOptions({ touchExtend: true });
+    L.Map.TouchExtend = L.Handler.extend({
+        initialize: function (map) {
+            this._map = map;
+            this._container = map._container;
+            this._pane = map._panes.overlayPane;
+        },
+        addHooks: function () {
+            L.DomEvent.on(this._container, 'touchstart', this._onTouchStart, this);
+            L.DomEvent.on(this._container, 'touchend', this._onTouchEnd, this);
+            L.DomEvent.on(this._container, 'touchmove', this._onTouchMove, this);
+            if (this._detectIE()) {
+                L.DomEvent.on(this._container, 'MSPointerDown', this._onTouchStart, this);
+                L.DomEvent.on(this._container, 'MSPointerUp', this._onTouchEnd, this);
+                L.DomEvent.on(this._container, 'MSPointerMove', this._onTouchMove, this);
+                L.DomEvent.on(this._container, 'MSPointerCancel', this._onTouchCancel, this);
+            } else {
+                L.DomEvent.on(this._container, 'touchcancel', this._onTouchCancel, this);
+                L.DomEvent.on(this._container, 'touchleave', this._onTouchLeave, this);
+            }
+        },
+        removeHooks: function () {
+            L.DomEvent.off(this._container, 'touchstart', this._onTouchStart);
+            L.DomEvent.off(this._container, 'touchend', this._onTouchEnd);
+            L.DomEvent.off(this._container, 'touchmove', this._onTouchMove);
+            if (this._detectIE()) {
+                L.DomEvent.off(this._container, 'MSPointerDowm', this._onTouchStart);
+                L.DomEvent.off(this._container, 'MSPointerUp', this._onTouchEnd);
+                L.DomEvent.off(this._container, 'MSPointerMove', this._onTouchMove);
+                L.DomEvent.off(this._container, 'MSPointerCancel', this._onTouchCancel);
+            } else {
+                L.DomEvent.off(this._container, 'touchcancel', this._onTouchCancel);
+                L.DomEvent.off(this._container, 'touchleave', this._onTouchLeave);
+            }
+        },
+        _touchEvent: function (e, type) {
+            var touchEvent = {};
+            if (typeof e.touches !== 'undefined') {
+                if (!e.touches.length) {
+                    return;
+                }
+                touchEvent = e.touches[0];
+            } else if (e.pointerType === 'touch') {
+                touchEvent = e;
+                if (!this._filterClick(e)) {
+                    return;
+                }
+            } else {
+                return;
+            }
+            var containerPoint = this._map.mouseEventToContainerPoint(touchEvent), layerPoint = this._map.mouseEventToLayerPoint(touchEvent), latlng = this._map.layerPointToLatLng(layerPoint);
+            this._map.fire(type, {
+                latlng: latlng,
+                layerPoint: layerPoint,
+                containerPoint: containerPoint,
+                pageX: touchEvent.pageX,
+                pageY: touchEvent.pageY,
+                originalEvent: e
+            });
+        },
+        _filterClick: function (e) {
+            var timeStamp = e.timeStamp || e.originalEvent.timeStamp, elapsed = L.DomEvent._lastClick && timeStamp - L.DomEvent._lastClick;
+            if (elapsed && elapsed > 100 && elapsed < 500 || e.target._simulatedClick && !e._simulated) {
+                L.DomEvent.stop(e);
+                return false;
+            }
+            L.DomEvent._lastClick = timeStamp;
+            return true;
+        },
+        _onTouchStart: function (e) {
+            if (!this._map._loaded) {
+                return;
+            }
+            var type = 'touchstart';
+            this._touchEvent(e, type);
+        },
+        _onTouchEnd: function (e) {
+            if (!this._map._loaded) {
+                return;
+            }
+            var type = 'touchend';
+            this._touchEvent(e, type);
+        },
+        _onTouchCancel: function (e) {
+            if (!this._map._loaded) {
+                return;
+            }
+            var type = 'touchcancel';
+            if (this._detectIE()) {
+                type = 'pointercancel';
+            }
+            this._touchEvent(e, type);
+        },
+        _onTouchLeave: function (e) {
+            if (!this._map._loaded) {
+                return;
+            }
+            var type = 'touchleave';
+            this._touchEvent(e, type);
+        },
+        _onTouchMove: function (e) {
+            if (!this._map._loaded) {
+                return;
+            }
+            var type = 'touchmove';
+            this._touchEvent(e, type);
+        },
+        _detectIE: function () {
+            var ua = window.navigator.userAgent;
+            var msie = ua.indexOf('MSIE ');
+            if (msie > 0) {
+                return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
+            }
+            var trident = ua.indexOf('Trident/');
+            if (trident > 0) {
+                var rv = ua.indexOf('rv:');
+                return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
+            }
+            var edge = ua.indexOf('Edge/');
+            if (edge > 0) {
+                return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
+            }
+            return false;
+        }
+    });
+    L.Map.addInitHook('addHandler', 'touchExtend', L.Map.TouchExtend);
+    L.Marker.Touch = L.Marker.extend({
+        _initInteraction: function () {
+            if (!this.options.clickable) {
+                return;
+            }
+            var icon = this._icon, events = [
+                    'dblclick',
+                    'mousedown',
+                    'mouseover',
+                    'mouseout',
+                    'contextmenu',
+                    'touchstart',
+                    'touchend',
+                    'touchmove'
+                ];
+            if (this._detectIE) {
+                events.concat([
+                    'MSPointerDown',
+                    'MSPointerUp',
+                    'MSPointerMove',
+                    'MSPointerCancel'
+                ]);
+            } else {
+                events.concat(['touchcancel']);
+            }
+            L.DomUtil.addClass(icon, 'leaflet-clickable');
+            L.DomEvent.on(icon, 'click', this._onMouseClick, this);
+            L.DomEvent.on(icon, 'keypress', this._onKeyPress, this);
+            for (var i = 0; i < events.length; i++) {
+                L.DomEvent.on(icon, events[i], this._fireMouseEvent, this);
+            }
+            if (L.Handler.MarkerDrag) {
+                this.dragging = new L.Handler.MarkerDrag(this);
+                if (this.options.draggable) {
+                    this.dragging.enable();
+                }
+            }
+        },
+        _detectIE: function () {
+            var ua = window.navigator.userAgent;
+            var msie = ua.indexOf('MSIE ');
+            if (msie > 0) {
+                return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
+            }
+            var trident = ua.indexOf('Trident/');
+            if (trident > 0) {
+                var rv = ua.indexOf('rv:');
+                return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
+            }
+            var edge = ua.indexOf('Edge/');
+            if (edge > 0) {
+                return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
+            }
+            return false;
+        }
+    });
+    L.LatLngUtil = {
+        cloneLatLngs: function (latlngs) {
+            var clone = [];
+            for (var i = 0, l = latlngs.length; i < l; i++) {
+                clone.push(this.cloneLatLng(latlngs[i]));
+            }
+            return clone;
+        },
+        cloneLatLng: function (latlng) {
+            return L.latLng(latlng.lat, latlng.lng);
+        }
+    };
+    L.GeometryUtil = L.extend(L.GeometryUtil || {}, {
+        geodesicArea: function (latLngs) {
+            var pointsCount = latLngs.length, area = 0, d2r = L.LatLng.DEG_TO_RAD, p1, p2;
+            if (pointsCount > 2) {
+                for (var i = 0; i < pointsCount; i++) {
+                    p1 = latLngs[i];
+                    p2 = latLngs[(i + 1) % pointsCount];
+                    area += (p2.lng - p1.lng) * d2r * (2 + Math.sin(p1.lat * d2r) + Math.sin(p2.lat * d2r));
+                }
+                area = area * 6378137 * 6378137 / 2;
+            }
+            return Math.abs(area);
+        },
+        readableArea: function (area, isMetric) {
+            var areaStr;
+            if (isMetric) {
+                if (area >= 10000) {
+                    areaStr = (area * 0.0001).toFixed(2) + ' ha';
+                } else {
+                    areaStr = area.toFixed(2) + ' m&sup2;';
+                }
+            } else {
+                area /= 0.836127;
+                if (area >= 3097600) {
+                    areaStr = (area / 3097600).toFixed(2) + ' mi&sup2;';
+                } else if (area >= 4840) {
+                    areaStr = (area / 4840).toFixed(2) + ' acres';
+                } else {
+                    areaStr = Math.ceil(area) + ' yd&sup2;';
+                }
+            }
+            return areaStr;
+        },
+        readableDistance: function (distance, isMetric, useFeet) {
+            var distanceStr;
+            if (isMetric) {
+                if (distance > 1000) {
+                    distanceStr = (distance / 1000).toFixed(2) + ' km';
+                } else {
+                    distanceStr = Math.ceil(distance) + ' m';
+                }
+            } else {
+                distance *= 1.09361;
+                if (distance > 1760) {
+                    distanceStr = (distance / 1760).toFixed(2) + ' miles';
+                } else {
+                    var suffix = ' yd';
+                    if (useFeet) {
+                        distance = distance * 3;
+                        suffix = ' ft';
+                    }
+                    distanceStr = Math.ceil(distance) + suffix;
+                }
+            }
+            return distanceStr;
+        }
+    });
+    L.Util.extend(L.LineUtil, {
+        segmentsIntersect: function (p, p1, p2, p3) {
+            return this._checkCounterclockwise(p, p2, p3) !== this._checkCounterclockwise(p1, p2, p3) && this._checkCounterclockwise(p, p1, p2) !== this._checkCounterclockwise(p, p1, p3);
+        },
+        _checkCounterclockwise: function (p, p1, p2) {
+            return (p2.y - p.y) * (p1.x - p.x) > (p1.y - p.y) * (p2.x - p.x);
+        }
+    });
+    L.Polyline.include({
+        intersects: function () {
+            var points = this._originalPoints, len = points ? points.length : 0, i, p, p1;
+            if (this._tooFewPointsForIntersection()) {
+                return false;
+            }
+            for (i = len - 1; i >= 3; i--) {
+                p = points[i - 1];
+                p1 = points[i];
+                if (this._lineSegmentsIntersectsRange(p, p1, i - 2)) {
+                    return true;
+                }
+            }
+            return false;
+        },
+        newLatLngIntersects: function (latlng, skipFirst) {
+            if (!this._map) {
+                return false;
+            }
+            return this.newPointIntersects(this._map.latLngToLayerPoint(latlng), skipFirst);
+        },
+        newPointIntersects: function (newPoint, skipFirst) {
+            var points = this._originalPoints, len = points ? points.length : 0, lastPoint = points ? points[len - 1] : null, maxIndex = len - 2;
+            if (this._tooFewPointsForIntersection(1)) {
+                return false;
+            }
+            return this._lineSegmentsIntersectsRange(lastPoint, newPoint, maxIndex, skipFirst ? 1 : 0);
+        },
+        _tooFewPointsForIntersection: function (extraPoints) {
+            var points = this._originalPoints, len = points ? points.length : 0;
+            len += extraPoints || 0;
+            return !this._originalPoints || len <= 3;
+        },
+        _lineSegmentsIntersectsRange: function (p, p1, maxIndex, minIndex) {
+            var points = this._originalPoints, p2, p3;
+            minIndex = minIndex || 0;
+            for (var j = maxIndex; j > minIndex; j--) {
+                p2 = points[j - 1];
+                p3 = points[j];
+                if (L.LineUtil.segmentsIntersect(p, p1, p2, p3)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    });
+    L.Polygon.include({
+        intersects: function () {
+            var polylineIntersects, points = this._originalPoints, len, firstPoint, lastPoint, maxIndex;
+            if (this._tooFewPointsForIntersection()) {
+                return false;
+            }
+            polylineIntersects = L.Polyline.prototype.intersects.call(this);
+            if (polylineIntersects) {
+                return true;
+            }
+            len = points.length;
+            firstPoint = points[0];
+            lastPoint = points[len - 1];
+            maxIndex = len - 2;
+            return this._lineSegmentsIntersectsRange(lastPoint, firstPoint, maxIndex, 1);
+        }
+    });
+    L.Control.Draw = L.Control.extend({
+        options: {
+            position: 'topleft',
+            draw: {},
+            edit: false
+        },
+        initialize: function (options) {
+            if (L.version < '0.7') {
+                throw new Error('Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/');
+            }
+            L.Control.prototype.initialize.call(this, options);
+            var toolbar;
+            this._toolbars = {};
+            if (L.DrawToolbar && this.options.draw) {
+                toolbar = new L.DrawToolbar(this.options.draw);
+                this._toolbars[L.DrawToolbar.TYPE] = toolbar;
+                this._toolbars[L.DrawToolbar.TYPE].on('enable', this._toolbarEnabled, this);
+            }
+            if (L.EditToolbar && this.options.edit) {
+                toolbar = new L.EditToolbar(this.options.edit);
+                this._toolbars[L.EditToolbar.TYPE] = toolbar;
+                this._toolbars[L.EditToolbar.TYPE].on('enable', this._toolbarEnabled, this);
+            }
+            L.toolbar = this;
+        },
+        onAdd: function (map) {
+            var container = L.DomUtil.create('div', 'leaflet-draw'), addedTopClass = false, topClassName = 'leaflet-draw-toolbar-top', toolbarContainer;
+            for (var toolbarId in this._toolbars) {
+                if (this._toolbars.hasOwnProperty(toolbarId)) {
+                    toolbarContainer = this._toolbars[toolbarId].addToolbar(map);
+                    if (toolbarContainer) {
+                        if (!addedTopClass) {
+                            if (!L.DomUtil.hasClass(toolbarContainer, topClassName)) {
+                                L.DomUtil.addClass(toolbarContainer.childNodes[0], topClassName);
+                            }
+                            addedTopClass = true;
+                        }
+                        container.appendChild(toolbarContainer);
+                    }
+                }
+            }
+            return container;
+        },
+        onRemove: function () {
+            for (var toolbarId in this._toolbars) {
+                if (this._toolbars.hasOwnProperty(toolbarId)) {
+                    this._toolbars[toolbarId].removeToolbar();
+                }
+            }
+        },
+        setDrawingOptions: function (options) {
+            for (var toolbarId in this._toolbars) {
+                if (this._toolbars[toolbarId] instanceof L.DrawToolbar) {
+                    this._toolbars[toolbarId].setOptions(options);
+                }
+            }
+        },
+        _toolbarEnabled: function (e) {
+            var enabledToolbar = e.target;
+            for (var toolbarId in this._toolbars) {
+                if (this._toolbars[toolbarId] !== enabledToolbar) {
+                    this._toolbars[toolbarId].disable();
+                }
+            }
+        }
+    });
+    L.Map.mergeOptions({
+        drawControlTooltips: true,
+        drawControl: false
+    });
+    L.Map.addInitHook(function () {
+        if (this.options.drawControl) {
+            this.drawControl = new L.Control.Draw();
+            this.addControl(this.drawControl);
+        }
+    });
+    L.Toolbar = L.Class.extend({
+        includes: [L.Mixin.Events],
+        initialize: function (options) {
+            L.setOptions(this, options);
+            this._modes = {};
+            this._actionButtons = [];
+            this._activeMode = null;
+        },
+        enabled: function () {
+            return this._activeMode !== null;
+        },
+        disable: function () {
+            if (!this.enabled()) {
+                return;
+            }
+            this._activeMode.handler.disable();
+        },
+        addToolbar: function (map) {
+            var container = L.DomUtil.create('div', 'leaflet-draw-section'), buttonIndex = 0, buttonClassPrefix = this._toolbarClass || '', modeHandlers = this.getModeHandlers(map), i;
+            this._toolbarContainer = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
+            this._map = map;
+            for (i = 0; i < modeHandlers.length; i++) {
+                if (modeHandlers[i].enabled) {
+                    this._initModeHandler(modeHandlers[i].handler, this._toolbarContainer, buttonIndex++, buttonClassPrefix, modeHandlers[i].title);
+                }
+            }
+            if (!buttonIndex) {
+                return;
+            }
+            this._lastButtonIndex = --buttonIndex;
+            this._actionsContainer = L.DomUtil.create('ul', 'leaflet-draw-actions');
+            container.appendChild(this._toolbarContainer);
+            container.appendChild(this._actionsContainer);
+            return container;
+        },
+        removeToolbar: function () {
+            for (var handlerId in this._modes) {
+                if (this._modes.hasOwnProperty(handlerId)) {
+                    this._disposeButton(this._modes[handlerId].button, this._modes[handlerId].handler.enable, this._modes[handlerId].handler);
+                    this._modes[handlerId].handler.disable();
+                    this._modes[handlerId].handler.off('enabled', this._handlerActivated, this).off('disabled', this._handlerDeactivated, this);
+                }
+            }
+            this._modes = {};
+            for (var i = 0, l = this._actionButtons.length; i < l; i++) {
+                this._disposeButton(this._actionButtons[i].button, this._actionButtons[i].callback, this);
+            }
+            this._actionButtons = [];
+            this._actionsContainer = null;
+        },
+        _initModeHandler: function (handler, container, buttonIndex, classNamePredix, buttonTitle) {
+            var type = handler.type;
+            this._modes[type] = {};
+            this._modes[type].handler = handler;
+            this._modes[type].button = this._createButton({
+                type: type,
+                title: buttonTitle,
+                className: classNamePredix + '-' + type,
+                container: container,
+                callback: this._modes[type].handler.enable,
+                context: this._modes[type].handler
+            });
+            this._modes[type].buttonIndex = buttonIndex;
+            this._modes[type].handler.on('enabled', this._handlerActivated, this).on('disabled', this._handlerDeactivated, this);
+        },
+        _createButton: function (options) {
+            var link = L.DomUtil.create('a', options.className || '', options.container);
+            link.href = '#';
+            if (options.text) {
+                link.innerHTML = options.text;
+            }
+            if (options.title) {
+                link.title = options.title;
+            }
+            L.DomEvent.on(link, 'click', L.DomEvent.stopPropagation).on(link, 'mousedown', L.DomEvent.stopPropagation).on(link, 'dblclick', L.DomEvent.stopPropagation).on(link, 'click', L.DomEvent.preventDefault).on(link, 'click', options.callback, options.context);
+            return link;
+        },
+        _disposeButton: function (button, callback) {
+            L.DomEvent.off(button, 'click', L.DomEvent.stopPropagation).off(button, 'mousedown', L.DomEvent.stopPropagation).off(button, 'dblclick', L.DomEvent.stopPropagation).off(button, 'click', L.DomEvent.preventDefault).off(button, 'click', callback);
+        },
+        _handlerActivated: function (e) {
+            this.disable();
+            this._activeMode = this._modes[e.handler];
+            L.DomUtil.addClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
+            this._showActionsToolbar();
+            this.fire('enable');
+        },
+        _handlerDeactivated: function () {
+            this._hideActionsToolbar();
+            L.DomUtil.removeClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
+            this._activeMode = null;
+            this.fire('disable');
+        },
+        _createActions: function (handler) {
+            var container = this._actionsContainer, buttons = this.getActions(handler), l = buttons.length, li, di, dl, button;
+            for (di = 0, dl = this._actionButtons.length; di < dl; di++) {
+                this._disposeButton(this._actionButtons[di].button, this._actionButtons[di].callback);
+            }
+            this._actionButtons = [];
+            while (container.firstChild) {
+                container.removeChild(container.firstChild);
+            }
+            for (var i = 0; i < l; i++) {
+                if ('enabled' in buttons[i] && !buttons[i].enabled) {
+                    continue;
+                }
+                li = L.DomUtil.create('li', '', container);
+                button = this._createButton({
+                    title: buttons[i].title,
+                    text: buttons[i].text,
+                    container: li,
+                    callback: buttons[i].callback,
+                    context: buttons[i].context
+                });
+                this._actionButtons.push({
+                    button: button,
+                    callback: buttons[i].callback
+                });
+            }
+        },
+        _showActionsToolbar: function () {
+            var buttonIndex = this._activeMode.buttonIndex, lastButtonIndex = this._lastButtonIndex, toolbarPosition = this._activeMode.button.offsetTop - 1;
+            this._createActions(this._activeMode.handler);
+            this._actionsContainer.style.top = toolbarPosition + 'px';
+            if (buttonIndex === 0) {
+                L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
+                L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-top');
+            }
+            if (buttonIndex === lastButtonIndex) {
+                L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
+                L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
+            }
+            this._actionsContainer.style.display = 'block';
+        },
+        _hideActionsToolbar: function () {
+            this._actionsContainer.style.display = 'none';
+            L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
+            L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
+            L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-top');
+            L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
+        }
+    });
+    L.Tooltip = L.Class.extend({
+        initialize: function (map) {
+            this._map = map;
+            this._popupPane = map._panes.popupPane;
+            this._container = map.options.drawControlTooltips ? L.DomUtil.create('div', 'leaflet-draw-tooltip', this._popupPane) : null;
+            this._singleLineLabel = false;
+            this._map.on('mouseout', this._onMouseOut, this);
+        },
+        dispose: function () {
+            this._map.off('mouseout', this._onMouseOut, this);
+            if (this._container) {
+                this._popupPane.removeChild(this._container);
+                this._container = null;
+            }
+        },
+        updateContent: function (labelText) {
+            if (!this._container) {
+                return this;
+            }
+            labelText.subtext = labelText.subtext || '';
+            if (labelText.subtext.length === 0 && !this._singleLineLabel) {
+                L.DomUtil.addClass(this._container, 'leaflet-draw-tooltip-single');
+                this._singleLineLabel = true;
+            } else if (labelText.subtext.length > 0 && this._singleLineLabel) {
+                L.DomUtil.removeClass(this._container, 'leaflet-draw-tooltip-single');
+                this._singleLineLabel = false;
+            }
+            this._container.innerHTML = (labelText.subtext.length > 0 ? '<span class="leaflet-draw-tooltip-subtext">' + labelText.subtext + '</span>' + '<br />' : '') + '<span>' + labelText.text + '</span>';
+            return this;
+        },
+        updatePosition: function (latlng) {
+            var pos = this._map.latLngToLayerPoint(latlng), tooltipContainer = this._container;
+            if (this._container) {
+                tooltipContainer.style.visibility = 'inherit';
+                L.DomUtil.setPosition(tooltipContainer, pos);
+            }
+            return this;
+        },
+        showAsError: function () {
+            if (this._container) {
+                L.DomUtil.addClass(this._container, 'leaflet-error-draw-tooltip');
+            }
+            return this;
+        },
+        removeError: function () {
+            if (this._container) {
+                L.DomUtil.removeClass(this._container, 'leaflet-error-draw-tooltip');
+            }
+            return this;
+        },
+        _onMouseOut: function () {
+            if (this._container) {
+                this._container.style.visibility = 'hidden';
+            }
+        }
+    });
+    L.DrawToolbar = L.Toolbar.extend({
+        statics: { TYPE: 'draw' },
+        options: {
+            polyline: {},
+            polygon: {},
+            rectangle: {},
+            circle: {},
+            marker: {}
+        },
+        initialize: function (options) {
+            for (var type in this.options) {
+                if (this.options.hasOwnProperty(type)) {
+                    if (options[type]) {
+                        options[type] = L.extend({}, this.options[type], options[type]);
+                    }
+                }
+            }
+            this._toolbarClass = 'leaflet-draw-draw';
+            L.Toolbar.prototype.initialize.call(this, options);
+        },
+        getModeHandlers: function (map) {
+            return [
+                {
+                    enabled: this.options.polyline,
+                    handler: new L.Draw.Polyline(map, this.options.polyline),
+                    title: L.drawLocal.draw.toolbar.buttons.polyline
+                },
+                {
+                    enabled: this.options.polygon,
+                    handler: new L.Draw.Polygon(map, this.options.polygon),
+                    title: L.drawLocal.draw.toolbar.buttons.polygon
+                },
+                {
+                    enabled: this.options.rectangle,
+                    handler: new L.Draw.Rectangle(map, this.options.rectangle),
+                    title: L.drawLocal.draw.toolbar.buttons.rectangle
+                },
+                {
+                    enabled: this.options.circle,
+                    handler: new L.Draw.Circle(map, this.options.circle),
+                    title: L.drawLocal.draw.toolbar.buttons.circle
+                },
+                {
+                    enabled: this.options.marker,
+                    handler: new L.Draw.Marker(map, this.options.marker),
+                    title: L.drawLocal.draw.toolbar.buttons.marker
+                }
+            ];
+        },
+        getActions: function (handler) {
+            return [
+                {
+                    enabled: handler.completeShape,
+                    title: L.drawLocal.draw.toolbar.finish.title,
+                    text: L.drawLocal.draw.toolbar.finish.text,
+                    callback: handler.completeShape,
+                    context: handler
+                },
+                {
+                    enabled: handler.deleteLastVertex,
+                    title: L.drawLocal.draw.toolbar.undo.title,
+                    text: L.drawLocal.draw.toolbar.undo.text,
+                    callback: handler.deleteLastVertex,
+                    context: handler
+                },
+                {
+                    title: L.drawLocal.draw.toolbar.actions.title,
+                    text: L.drawLocal.draw.toolbar.actions.text,
+                    callback: this.disable,
+                    context: this
+                }
+            ];
+        },
+        setOptions: function (options) {
+            L.setOptions(this, options);
+            for (var type in this._modes) {
+                if (this._modes.hasOwnProperty(type) && options.hasOwnProperty(type)) {
+                    this._modes[type].handler.setOptions(options[type]);
+                }
+            }
+        }
+    });
+    L.EditToolbar = L.Toolbar.extend({
+        statics: { TYPE: 'edit' },
+        options: {
+            edit: {
+                selectedPathOptions: {
+                    dashArray: '10, 10',
+                    fill: true,
+                    fillColor: '#fe57a1',
+                    fillOpacity: 0.1,
+                    maintainColor: false
+                }
+            },
+            remove: {},
+            featureGroup: null
+        },
+        initialize: function (options) {
+            if (options.edit) {
+                if (typeof options.edit.selectedPathOptions === 'undefined') {
+                    options.edit.selectedPathOptions = this.options.edit.selectedPathOptions;
+                }
+                options.edit.selectedPathOptions = L.extend({}, this.options.edit.selectedPathOptions, options.edit.selectedPathOptions);
+            }
+            if (options.remove) {
+                options.remove = L.extend({}, this.options.remove, options.remove);
+            }
+            this._toolbarClass = 'leaflet-draw-edit';
+            L.Toolbar.prototype.initialize.call(this, options);
+            this._selectedFeatureCount = 0;
+        },
+        getModeHandlers: function (map) {
+            var featureGroup = this.options.featureGroup;
+            return [
+                {
+                    enabled: this.options.edit,
+                    handler: new L.EditToolbar.Edit(map, {
+                        featureGroup: featureGroup,
+                        selectedPathOptions: this.options.edit.selectedPathOptions
+                    }),
+                    title: L.drawLocal.edit.toolbar.buttons.edit
+                },
+                {
+                    enabled: this.options.remove,
+                    handler: new L.EditToolbar.Delete(map, { featureGroup: featureGroup }),
+                    title: L.drawLocal.edit.toolbar.buttons.remove
+                }
+            ];
+        },
+        getActions: function () {
+            return [
+                {
+                    title: L.drawLocal.edit.toolbar.actions.save.title,
+                    text: L.drawLocal.edit.toolbar.actions.save.text,
+                    callback: this._save,
+                    context: this
+                },
+                {
+                    title: L.drawLocal.edit.toolbar.actions.cancel.title,
+                    text: L.drawLocal.edit.toolbar.actions.cancel.text,
+                    callback: this.disable,
+                    context: this
+                }
+            ];
+        },
+        addToolbar: function (map) {
+            var container = L.Toolbar.prototype.addToolbar.call(this, map);
+            this._checkDisabled();
+            this.options.featureGroup.on('layeradd layerremove', this._checkDisabled, this);
+            return container;
+        },
+        removeToolbar: function () {
+            this.options.featureGroup.off('layeradd layerremove', this._checkDisabled, this);
+            L.Toolbar.prototype.removeToolbar.call(this);
+        },
+        disable: function () {
+            if (!this.enabled()) {
+                return;
+            }
+            this._activeMode.handler.revertLayers();
+            L.Toolbar.prototype.disable.call(this);
+        },
+        _save: function () {
+            this._activeMode.handler.save();
+            this._activeMode.handler.disable();
+        },
+        _checkDisabled: function () {
+            var featureGroup = this.options.featureGroup, hasLayers = featureGroup.getLayers().length !== 0, button;
+            if (this.options.edit) {
+                button = this._modes[L.EditToolbar.Edit.TYPE].button;
+                if (hasLayers) {
+                    L.DomUtil.removeClass(button, 'leaflet-disabled');
+                } else {
+                    L.DomUtil.addClass(button, 'leaflet-disabled');
+                }
+                button.setAttribute('title', hasLayers ? L.drawLocal.edit.toolbar.buttons.edit : L.drawLocal.edit.toolbar.buttons.editDisabled);
+            }
+            if (this.options.remove) {
+                button = this._modes[L.EditToolbar.Delete.TYPE].button;
+                if (hasLayers) {
+                    L.DomUtil.removeClass(button, 'leaflet-disabled');
+                } else {
+                    L.DomUtil.addClass(button, 'leaflet-disabled');
+                }
+                button.setAttribute('title', hasLayers ? L.drawLocal.edit.toolbar.buttons.remove : L.drawLocal.edit.toolbar.buttons.removeDisabled);
+            }
+        }
+    });
+    L.EditToolbar.Edit = L.Handler.extend({
+        statics: { TYPE: 'edit' },
+        includes: L.Mixin.Events,
+        initialize: function (map, options) {
+            L.Handler.prototype.initialize.call(this, map);
+            L.setOptions(this, options);
+            this._featureGroup = options.featureGroup;
+            if (!(this._featureGroup instanceof L.FeatureGroup)) {
+                throw new Error('options.featureGroup must be a L.FeatureGroup');
+            }
+            this._uneditedLayerProps = {};
+            this.type = L.EditToolbar.Edit.TYPE;
+        },
+        enable: function () {
+            if (this._enabled || !this._hasAvailableLayers()) {
+                return;
+            }
+            this.fire('enabled', { handler: this.type });
+            this._map.fire('draw:editstart', { handler: this.type });
+            L.Handler.prototype.enable.call(this);
+            this._featureGroup.on('layeradd', this._enableLayerEdit, this).on('layerremove', this._disableLayerEdit, this);
+        },
+        disable: function () {
+            if (!this._enabled) {
+                return;
+            }
+            this._featureGroup.off('layeradd', this._enableLayerEdit, this).off('layerremove', this._disableLayerEdit, this);
+            L.Handler.prototype.disable.call(this);
+            this._map.fire('draw:editstop', { handler: this.type });
+            this.fire('disabled', { handler: this.type });
+        },
+        addHooks: function () {
+            var map = this._map;
+            if (map) {
+                map.getContainer().focus();
+                this._featureGroup.eachLayer(this._enableLayerEdit, this);
+                this._tooltip = new L.Tooltip(this._map);
+                this._updateTooltip();
+                this._map.on('mousemove', this._onMouseMove, this).on('touchmove', this._onMouseMove, this).on('MSPointerMove', this._onMouseMove, this).on('click', this._editStyle, this).on('draw:editvertex', this._updateTooltip, this);
+            }
+        },
+        removeHooks: function () {
+            if (this._map) {
+                this._featureGroup.eachLayer(this._disableLayerEdit, this);
+                this._uneditedLayerProps = {};
+                this._tooltip.dispose();
+                this._tooltip = null;
+                this._map.off('mousemove', this._onMouseMove, this).off('touchmove', this._onMouseMove, this).off('MSPointerMove', this._onMouseMove, this);
+            }
+        },
+        revertLayers: function () {
+            this._featureGroup.eachLayer(function (layer) {
+                this._revertLayer(layer);
+            }, this);
+        },
+        save: function () {
+            var editedLayers = new L.LayerGroup();
+            this._featureGroup.eachLayer(function (layer) {
+                if (layer.edited) {
+                    editedLayers.addLayer(layer);
+                    layer.edited = false;
+                }
+            });
+            this._map.fire('draw:edited', { layers: editedLayers });
+        },
+        _backupLayer: function (layer) {
+            var id = L.Util.stamp(layer);
+            if (!this._uneditedLayerProps[id]) {
+                if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
+                    this._uneditedLayerProps[id] = { latlngs: L.LatLngUtil.cloneLatLngs(layer.getLatLngs()) };
+                } else if (layer instanceof L.Circle) {
+                    this._uneditedLayerProps[id] = {
+                        latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()),
+                        radius: layer.getRadius()
+                    };
+                } else if (layer instanceof L.Marker) {
+                    this._uneditedLayerProps[id] = { latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()) };
+                }
+            }
+        },
+        _getTooltipText: function () {
+            return {
+                text: L.drawLocal.edit.handlers.edit.tooltip.text,
+                subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext
+            };
+        },
+        _updateTooltip: function () {
+            this._tooltip.updateContent(this._getTooltipText());
+        },
+        _revertLayer: function (layer) {
+            var id = L.Util.stamp(layer);
+            layer.edited = false;
+            if (this._uneditedLayerProps.hasOwnProperty(id)) {
+                if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) {
+                    layer.setLatLngs(this._uneditedLayerProps[id].latlngs);
+                } else if (layer instanceof L.Circle) {
+                    layer.setLatLng(this._uneditedLayerProps[id].latlng);
+                    layer.setRadius(this._uneditedLayerProps[id].radius);
+                } else if (layer instanceof L.Marker) {
+                    layer.setLatLng(this._uneditedLayerProps[id].latlng);
+                }
+                layer.fire('revert-edited', { layer: layer });
+            }
+        },
+        _enableLayerEdit: function (e) {
+            var layer = e.layer || e.target || e, pathOptions;
+            this._backupLayer(layer);
+            if (this.options.selectedPathOptions) {
+                pathOptions = L.Util.extend({}, this.options.selectedPathOptions);
+                if (pathOptions.maintainColor) {
+                    pathOptions.color = layer.options.color;
+                    pathOptions.fillColor = layer.options.fillColor;
+                }
+                layer.options.original = L.extend({}, layer.options);
+                layer.options.editing = pathOptions;
+            }
+            if (this.isMarker) {
+                layer.dragging.enable();
+                layer.on('dragend', this._onMarkerDragEnd).on('touchmove', this._onTouchMove, this).on('MSPointerMove', this._onTouchMove, this).on('touchend', this._onMarkerDragEnd, this).on('MSPointerUp', this._onMarkerDragEnd, this);
+            } else {
+                layer.editing.enable();
+            }
+        },
+        _disableLayerEdit: function (e) {
+            var layer = e.layer || e.target || e;
+            layer.edited = false;
+            layer.editing.disable();
+            delete layer.options.editing;
+            delete layer.options.original;
+            if (this._selectedPathOptions) {
+                if (layer instanceof L.Marker) {
+                    this._toggleMarkerHighlight(layer);
+                } else {
+                    layer.setStyle(layer.options.previousOptions);
+                    delete layer.options.previousOptions;
+                }
+            }
+            if (layer instanceof L.Marker) {
+                layer.dragging.disable();
+                layer.off('dragend', this._onMarkerDragEnd, this).off('touchmove', this._onTouchMove, this).off('MSPointerMove', this._onTouchMove, this).off('touchend', this._onMarkerDragEnd, this).off('MSPointerUp', this._onMarkerDragEnd, this);
+            } else {
+                layer.editing.disable();
+            }
+        },
+        _onMouseMove: function (e) {
+            this._tooltip.updatePosition(e.latlng);
+        },
+        _onTouchMove: function (e) {
+            var touchEvent = e.originalEvent.changedTouches[0], layerPoint = this._map.mouseEventToLayerPoint(touchEvent), latlng = this._map.layerPointToLatLng(layerPoint);
+            e.target.setLatLng(latlng);
+        },
+        _hasAvailableLayers: function () {
+            return this._featureGroup.getLayers().length !== 0;
+        }
+    });
+    L.EditToolbar.Delete = L.Handler.extend({
+        statics: { TYPE: 'remove' },
+        includes: L.Mixin.Events,
+        initialize: function (map, options) {
+            L.Handler.prototype.initialize.call(this, map);
+            L.Util.setOptions(this, options);
+            this._deletableLayers = this.options.featureGroup;
+            if (!(this._deletableLayers instanceof L.FeatureGroup)) {
+                throw new Error('options.featureGroup must be a L.FeatureGroup');
+            }
+            this.type = L.EditToolbar.Delete.TYPE;
+        },
+        enable: function () {
+            if (this._enabled || !this._hasAvailableLayers()) {
+                return;
+            }
+            this.fire('enabled', { handler: this.type });
+            this._map.fire('draw:deletestart', { handler: this.type });
+            L.Handler.prototype.enable.call(this);
+            this._deletableLayers.on('layeradd', this._enableLayerDelete, this).on('layerremove', this._disableLayerDelete, this);
+        },
+        disable: function () {
+            if (!this._enabled) {
+                return;
+            }
+            this._deletableLayers.off('layeradd', this._enableLayerDelete, this).off('layerremove', this._disableLayerDelete, this);
+            L.Handler.prototype.disable.call(this);
+            this._map.fire('draw:deletestop', { handler: this.type });
+            this.fire('disabled', { handler: this.type });
+        },
+        addHooks: function () {
+            var map = this._map;
+            if (map) {
+                map.getContainer().focus();
+                this._deletableLayers.eachLayer(this._enableLayerDelete, this);
+                this._deletedLayers = new L.LayerGroup();
+                this._tooltip = new L.Tooltip(this._map);
+                this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.remove.tooltip.text });
+                this._map.on('mousemove', this._onMouseMove, this);
+            }
+        },
+        removeHooks: function () {
+            if (this._map) {
+                this._deletableLayers.eachLayer(this._disableLayerDelete, this);
+                this._deletedLayers = null;
+                this._tooltip.dispose();
+                this._tooltip = null;
+                this._map.off('mousemove', this._onMouseMove, this);
+            }
+        },
+        revertLayers: function () {
+            this._deletedLayers.eachLayer(function (layer) {
+                this._deletableLayers.addLayer(layer);
+                layer.fire('revert-deleted', { layer: layer });
+            }, this);
+        },
+        save: function () {
+            this._map.fire('draw:deleted', { layers: this._deletedLayers });
+        },
+        _enableLayerDelete: function (e) {
+            var layer = e.layer || e.target || e;
+            layer.on('click', this._removeLayer, this);
+        },
+        _disableLayerDelete: function (e) {
+            var layer = e.layer || e.target || e;
+            layer.off('click', this._removeLayer, this);
+            this._deletedLayers.removeLayer(layer);
+        },
+        _removeLayer: function (e) {
+            var layer = e.layer || e.target || e;
+            this._deletableLayers.removeLayer(layer);
+            this._deletedLayers.addLayer(layer);
+            layer.fire('deleted');
+        },
+        _onMouseMove: function (e) {
+            this._tooltip.updatePosition(e.latlng);
+        },
+        _hasAvailableLayers: function () {
+            return this._deletableLayers.getLayers().length !== 0;
+        }
+    });
+}(window, document));
+leafletDraw = undefined;
+(function (factory) {
+    'use strict';
+    if (true) {
+        sortable = function () {
+            return typeof factory === 'function' ? factory() : factory;
+        }();
+    } else if (typeof module != 'undefined' && typeof module.exports != 'undefined') {
+        module.exports = factory();
+    } else if (typeof Package !== 'undefined') {
+        Sortable = factory();
+    } else {
+        window['Sortable'] = factory();
+    }
+}(function () {
+    'use strict';
+    if (typeof window == 'undefined' || typeof window.document == 'undefined') {
+        return function () {
+            throw new Error('Sortable.js requires a window with a document');
+        };
+    }
+    var dragEl, parentEl, ghostEl, cloneEl, rootEl, nextEl, scrollEl, scrollParentEl, lastEl, lastCSS, lastParentCSS, oldIndex, newIndex, activeGroup, autoScroll = {}, tapEvt, touchEvt, moved, RSPACE = /\s+/g, expando = 'Sortable' + new Date().getTime(), win = window, document = win.document, parseInt = win.parseInt, supportDraggable = !!('draggable' in document.createElement('div')), supportCssPointerEvents = function (el) {
+            el = document.createElement('x');
+            el.style.cssText = 'pointer-events:auto';
+            return el.style.pointerEvents === 'auto';
+        }(), _silent = false, abs = Math.abs, slice = [].slice, touchDragOverListeners = [], _autoScroll = _throttle(function (evt, options, rootEl) {
+            if (rootEl && options.scroll) {
+                var el, rect, sens = options.scrollSensitivity, speed = options.scrollSpeed, x = evt.clientX, y = evt.clientY, winWidth = window.innerWidth, winHeight = window.innerHeight, vx, vy;
+                if (scrollParentEl !== rootEl) {
+                    scrollEl = options.scroll;
+                    scrollParentEl = rootEl;
+                    if (scrollEl === true) {
+                        scrollEl = rootEl;
+                        do {
+                            if (scrollEl.offsetWidth < scrollEl.scrollWidth || scrollEl.offsetHeight < scrollEl.scrollHeight) {
+                                break;
+                            }
+                        } while (scrollEl = scrollEl.parentNode);
+                    }
+                }
+                if (scrollEl) {
+                    el = scrollEl;
+                    rect = scrollEl.getBoundingClientRect();
+                    vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens);
+                    vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens);
+                }
+                if (!(vx || vy)) {
+                    vx = (winWidth - x <= sens) - (x <= sens);
+                    vy = (winHeight - y <= sens) - (y <= sens);
+                    (vx || vy) && (el = win);
+                }
+                if (autoScroll.vx !== vx || autoScroll.vy !== vy || autoScroll.el !== el) {
+                    autoScroll.el = el;
+                    autoScroll.vx = vx;
+                    autoScroll.vy = vy;
+                    clearInterval(autoScroll.pid);
+                    if (el) {
+                        autoScroll.pid = setInterval(function () {
+                            if (el === win) {
+                                win.scrollTo(win.pageXOffset + vx * speed, win.pageYOffset + vy * speed);
+                            } else {
+                                vy && (el.scrollTop += vy * speed);
+                                vx && (el.scrollLeft += vx * speed);
+                            }
+                        }, 24);
+                    }
+                }
+            }
+        }, 30), _prepareGroup = function (options) {
+            var group = options.group;
+            if (!group || typeof group != 'object') {
+                group = options.group = { name: group };
+            }
+            [
+                'pull',
+                'put'
+            ].forEach(function (key) {
+                if (!(key in group)) {
+                    group[key] = true;
+                }
+            });
+            options.groups = ' ' + group.name + (group.put.join ? ' ' + group.put.join(' ') : '') + ' ';
+        };
+    function Sortable(el, options) {
+        if (!(el && el.nodeType && el.nodeType === 1)) {
+            throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el);
+        }
+        this.el = el;
+        this.options = options = _extend({}, options);
+        el[expando] = this;
+        var defaults = {
+            group: Math.random(),
+            sort: true,
+            disabled: false,
+            store: null,
+            handle: null,
+            scroll: true,
+            scrollSensitivity: 30,
+            scrollSpeed: 10,
+            draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*',
+            ghostClass: 'sortable-ghost',
+            chosenClass: 'sortable-chosen',
+            ignore: 'a, img',
+            filter: null,
+            animation: 0,
+            setData: function (dataTransfer, dragEl) {
+                dataTransfer.setData('Text', dragEl.textContent);
+            },
+            dropBubble: false,
+            dragoverBubble: false,
+            dataIdAttr: 'data-id',
+            delay: 0,
+            forceFallback: false,
+            fallbackClass: 'sortable-fallback',
+            fallbackOnBody: false
+        };
+        for (var name in defaults) {
+            !(name in options) && (options[name] = defaults[name]);
+        }
+        _prepareGroup(options);
+        for (var fn in this) {
+            if (fn.charAt(0) === '_') {
+                this[fn] = this[fn].bind(this);
+            }
+        }
+        this.nativeDraggable = options.forceFallback ? false : supportDraggable;
+        _on(el, 'mousedown', this._onTapStart);
+        _on(el, 'touchstart', this._onTapStart);
+        if (this.nativeDraggable) {
+            _on(el, 'dragover', this);
+            _on(el, 'dragenter', this);
+        }
+        touchDragOverListeners.push(this._onDragOver);
+        options.store && this.sort(options.store.get(this));
+    }
+    Sortable.prototype = {
+        constructor: Sortable,
+        _onTapStart: function (evt) {
+            var _this = this, el = this.el, options = this.options, type = evt.type, touch = evt.touches && evt.touches[0], target = (touch || evt).target, originalTarget = target, filter = options.filter;
+            if (type === 'mousedown' && evt.button !== 0 || options.disabled) {
+                return;
+            }
+            target = _closest(target, options.draggable, el);
+            if (!target) {
+                return;
+            }
+            oldIndex = _index(target, options.draggable);
+            if (typeof filter === 'function') {
+                if (filter.call(this, evt, target, this)) {
+                    _dispatchEvent(_this, originalTarget, 'filter', target, el, oldIndex);
+                    evt.preventDefault();
+                    return;
+                }
+            } else if (filter) {
+                filter = filter.split(',').some(function (criteria) {
+                    criteria = _closest(originalTarget, criteria.trim(), el);
+                    if (criteria) {
+                        _dispatchEvent(_this, criteria, 'filter', target, el, oldIndex);
+                        return true;
+                    }
+                });
+                if (filter) {
+                    evt.preventDefault();
+                    return;
+                }
+            }
+            if (options.handle && !_closest(originalTarget, options.handle, el)) {
+                return;
+            }
+            this._prepareDragStart(evt, touch, target);
+        },
+        _prepareDragStart: function (evt, touch, target) {
+            var _this = this, el = _this.el, options = _this.options, ownerDocument = el.ownerDocument, dragStartFn;
+            if (target && !dragEl && target.parentNode === el) {
+                tapEvt = evt;
+                rootEl = el;
+                dragEl = target;
+                parentEl = dragEl.parentNode;
+                nextEl = dragEl.nextSibling;
+                activeGroup = options.group;
+                dragStartFn = function () {
+                    _this._disableDelayedDrag();
+                    dragEl.draggable = true;
+                    _toggleClass(dragEl, _this.options.chosenClass, true);
+                    _this._triggerDragStart(touch);
+                };
+                options.ignore.split(',').forEach(function (criteria) {
+                    _find(dragEl, criteria.trim(), _disableDraggable);
+                });
+                _on(ownerDocument, 'mouseup', _this._onDrop);
+                _on(ownerDocument, 'touchend', _this._onDrop);
+                _on(ownerDocument, 'touchcancel', _this._onDrop);
+                if (options.delay) {
+                    _on(ownerDocument, 'mouseup', _this._disableDelayedDrag);
+                    _on(ownerDocument, 'touchend', _this._disableDelayedDrag);
+                    _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag);
+                    _on(ownerDocument, 'mousemove', _this._disableDelayedDrag);
+                    _on(ownerDocument, 'touchmove', _this._disableDelayedDrag);
+                    _this._dragStartTimer = setTimeout(dragStartFn, options.delay);
+                } else {
+                    dragStartFn();
+                }
+            }
+        },
+        _disableDelayedDrag: function () {
+            var ownerDocument = this.el.ownerDocument;
+            clearTimeout(this._dragStartTimer);
+            _off(ownerDocument, 'mouseup', this._disableDelayedDrag);
+            _off(ownerDocument, 'touchend', this._disableDelayedDrag);
+            _off(ownerDocument, 'touchcancel', this._disableDelayedDrag);
+            _off(ownerDocument, 'mousemove', this._disableDelayedDrag);
+            _off(ownerDocument, 'touchmove', this._disableDelayedDrag);
+        },
+        _triggerDragStart: function (touch) {
+            if (touch) {
+                tapEvt = {
+                    target: dragEl,
+                    clientX: touch.clientX,
+                    clientY: touch.clientY
+                };
+                this._onDragStart(tapEvt, 'touch');
+            } else if (!this.nativeDraggable) {
+                this._onDragStart(tapEvt, true);
+            } else {
+                _on(dragEl, 'dragend', this);
+                _on(rootEl, 'dragstart', this._onDragStart);
+            }
+            try {
+                if (document.selection) {
+                    document.selection.empty();
+                } else {
+                    window.getSelection().removeAllRanges();
+                }
+            } catch (err) {
+            }
+        },
+        _dragStarted: function () {
+            if (rootEl && dragEl) {
+                _toggleClass(dragEl, this.options.ghostClass, true);
+                Sortable.active = this;
+                _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, oldIndex);
+            }
+        },
+        _emulateDragOver: function () {
+            if (touchEvt) {
+                if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) {
+                    return;
+                }
+                this._lastX = touchEvt.clientX;
+                this._lastY = touchEvt.clientY;
+                if (!supportCssPointerEvents) {
+                    _css(ghostEl, 'display', 'none');
+                }
+                var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY), parent = target, groupName = ' ' + this.options.group.name + '', i = touchDragOverListeners.length;
+                if (parent) {
+                    do {
+                        if (parent[expando] && parent[expando].options.groups.indexOf(groupName) > -1) {
+                            while (i--) {
+                                touchDragOverListeners[i]({
+                                    clientX: touchEvt.clientX,
+                                    clientY: touchEvt.clientY,
+                                    target: target,
+                                    rootEl: parent
+                                });
+                            }
+                            break;
+                        }
+                        target = parent;
+                    } while (parent = parent.parentNode);
+                }
+                if (!supportCssPointerEvents) {
+                    _css(ghostEl, 'display', '');
+                }
+            }
+        },
+        _onTouchMove: function (evt) {
+            if (tapEvt) {
+                if (!Sortable.active) {
+                    this._dragStarted();
+                }
+                this._appendGhost();
+                var touch = evt.touches ? evt.touches[0] : evt, dx = touch.clientX - tapEvt.clientX, dy = touch.clientY - tapEvt.clientY, translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)';
+                moved = true;
+                touchEvt = touch;
+                _css(ghostEl, 'webkitTransform', translate3d);
+                _css(ghostEl, 'mozTransform', translate3d);
+                _css(ghostEl, 'msTransform', translate3d);
+                _css(ghostEl, 'transform', translate3d);
+                evt.preventDefault();
+            }
+        },
+        _appendGhost: function () {
+            if (!ghostEl) {
+                var rect = dragEl.getBoundingClientRect(), css = _css(dragEl), options = this.options, ghostRect;
+                ghostEl = dragEl.cloneNode(true);
+                _toggleClass(ghostEl, options.ghostClass, false);
+                _toggleClass(ghostEl, options.fallbackClass, true);
+                _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10));
+                _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10));
+                _css(ghostEl, 'width', rect.width);
+                _css(ghostEl, 'height', rect.height);
+                _css(ghostEl, 'opacity', '0.8');
+                _css(ghostEl, 'position', 'fixed');
+                _css(ghostEl, 'zIndex', '100000');
+                _css(ghostEl, 'pointerEvents', 'none');
+                options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl);
+                ghostRect = ghostEl.getBoundingClientRect();
+                _css(ghostEl, 'width', rect.width * 2 - ghostRect.width);
+                _css(ghostEl, 'height', rect.height * 2 - ghostRect.height);
+            }
+        },
+        _onDragStart: function (evt, useFallback) {
+            var dataTransfer = evt.dataTransfer, options = this.options;
+            this._offUpEvents();
+            if (activeGroup.pull == 'clone') {
+                cloneEl = dragEl.cloneNode(true);
+                _css(cloneEl, 'display', 'none');
+                rootEl.insertBefore(cloneEl, dragEl);
+            }
+            if (useFallback) {
+                if (useFallback === 'touch') {
+                    _on(document, 'touchmove', this._onTouchMove);
+                    _on(document, 'touchend', this._onDrop);
+                    _on(document, 'touchcancel', this._onDrop);
+                } else {
+                    _on(document, 'mousemove', this._onTouchMove);
+                    _on(document, 'mouseup', this._onDrop);
+                }
+                this._loopId = setInterval(this._emulateDragOver, 50);
+            } else {
+                if (dataTransfer) {
+                    dataTransfer.effectAllowed = 'move';
+                    options.setData && options.setData.call(this, dataTransfer, dragEl);
+                }
+                _on(document, 'drop', this);
+                setTimeout(this._dragStarted, 0);
+            }
+        },
+        _onDragOver: function (evt) {
+            var el = this.el, target, dragRect, revert, options = this.options, group = options.group, groupPut = group.put, isOwner = activeGroup === group, canSort = options.sort;
+            if (evt.preventDefault !== void 0) {
+                evt.preventDefault();
+                !options.dragoverBubble && evt.stopPropagation();
+            }
+            moved = true;
+            if (activeGroup && !options.disabled && (isOwner ? canSort || (revert = !rootEl.contains(dragEl)) : activeGroup.pull && groupPut && (activeGroup.name === group.name || groupPut.indexOf && ~groupPut.indexOf(activeGroup.name))) && (evt.rootEl === void 0 || evt.rootEl === this.el)) {
+                _autoScroll(evt, options, this.el);
+                if (_silent) {
+                    return;
+                }
+                target = _closest(evt.target, options.draggable, el);
+                dragRect = dragEl.getBoundingClientRect();
+                if (revert) {
+                    _cloneHide(true);
+                    if (cloneEl || nextEl) {
+                        rootEl.insertBefore(dragEl, cloneEl || nextEl);
+                    } else if (!canSort) {
+                        rootEl.appendChild(dragEl);
+                    }
+                    return;
+                }
+                if (el.children.length === 0 || el.children[0] === ghostEl || el === evt.target && (target = _ghostIsLast(el, evt))) {
+                    if (target) {
+                        if (target.animated) {
+                            return;
+                        }
+                        targetRect = target.getBoundingClientRect();
+                    }
+                    _cloneHide(isOwner);
+                    if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect) !== false) {
+                        if (!dragEl.contains(el)) {
+                            el.appendChild(dragEl);
+                            parentEl = el;
+                        }
+                        this._animate(dragRect, dragEl);
+                        target && this._animate(targetRect, target);
+                    }
+                } else if (target && !target.animated && target !== dragEl && target.parentNode[expando] !== void 0) {
+                    if (lastEl !== target) {
+                        lastEl = target;
+                        lastCSS = _css(target);
+                        lastParentCSS = _css(target.parentNode);
+                    }
+                    var targetRect = target.getBoundingClientRect(), width = targetRect.right - targetRect.left, height = targetRect.bottom - targetRect.top, floating = /left|right|inline/.test(lastCSS.cssFloat + lastCSS.display) || lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0, isWide = target.offsetWidth > dragEl.offsetWidth, isLong = target.offsetHeight > dragEl.offsetHeight, halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, nextSibling = target.nextElementSibling, moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect), after;
+                    if (moveVector !== false) {
+                        _silent = true;
+                        setTimeout(_unsilent, 30);
+                        _cloneHide(isOwner);
+                        if (moveVector === 1 || moveVector === -1) {
+                            after = moveVector === 1;
+                        } else if (floating) {
+                            var elTop = dragEl.offsetTop, tgTop = target.offsetTop;
+                            if (elTop === tgTop) {
+                                after = target.previousElementSibling === dragEl && !isWide || halfway && isWide;
+                            } else {
+                                after = tgTop > elTop;
+                            }
+                        } else {
+                            after = nextSibling !== dragEl && !isLong || halfway && isLong;
+                        }
+                        if (!dragEl.contains(el)) {
+                            if (after && !nextSibling) {
+                                el.appendChild(dragEl);
+                            } else {
+                                target.parentNode.insertBefore(dragEl, after ? nextSibling : target);
+                            }
+                        }
+                        parentEl = dragEl.parentNode;
+                        this._animate(dragRect, dragEl);
+                        this._animate(targetRect, target);
+                    }
+                }
+            }
+        },
+        _animate: function (prevRect, target) {
+            var ms = this.options.animation;
+            if (ms) {
+                var currentRect = target.getBoundingClientRect();
+                _css(target, 'transition', 'none');
+                _css(target, 'transform', 'translate3d(' + (prevRect.left - currentRect.left) + 'px,' + (prevRect.top - currentRect.top) + 'px,0)');
+                target.offsetWidth;
+                _css(target, 'transition', 'all ' + ms + 'ms');
+                _css(target, 'transform', 'translate3d(0,0,0)');
+                clearTimeout(target.animated);
+                target.animated = setTimeout(function () {
+                    _css(target, 'transition', '');
+                    _css(target, 'transform', '');
+                    target.animated = false;
+                }, ms);
+            }
+        },
+        _offUpEvents: function () {
+            var ownerDocument = this.el.ownerDocument;
+            _off(document, 'touchmove', this._onTouchMove);
+            _off(ownerDocument, 'mouseup', this._onDrop);
+            _off(ownerDocument, 'touchend', this._onDrop);
+            _off(ownerDocument, 'touchcancel', this._onDrop);
+        },
+        _onDrop: function (evt) {
+            var el = this.el, options = this.options;
+            clearInterval(this._loopId);
+            clearInterval(autoScroll.pid);
+            clearTimeout(this._dragStartTimer);
+            _off(document, 'mousemove', this._onTouchMove);
+            if (this.nativeDraggable) {
+                _off(document, 'drop', this);
+                _off(el, 'dragstart', this._onDragStart);
+            }
+            this._offUpEvents();
+            if (evt) {
+                if (moved) {
+                    evt.preventDefault();
+                    !options.dropBubble && evt.stopPropagation();
+                }
+                ghostEl && ghostEl.parentNode.removeChild(ghostEl);
+                if (dragEl) {
+                    if (this.nativeDraggable) {
+                        _off(dragEl, 'dragend', this);
+                    }
+                    _disableDraggable(dragEl);
+                    _toggleClass(dragEl, this.options.ghostClass, false);
+                    _toggleClass(dragEl, this.options.chosenClass, false);
+                    if (rootEl !== parentEl) {
+                        newIndex = _index(dragEl, options.draggable);
+                        if (newIndex >= 0) {
+                            _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
+                            _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
+                            _dispatchEvent(null, parentEl, 'add', dragEl, rootEl, oldIndex, newIndex);
+                            _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex);
+                        }
+                    } else {
+                        cloneEl && cloneEl.parentNode.removeChild(cloneEl);
+                        if (dragEl.nextSibling !== nextEl) {
+                            newIndex = _index(dragEl, options.draggable);
+                            if (newIndex >= 0) {
+                                _dispatchEvent(this, rootEl, 'update', dragEl, rootEl, oldIndex, newIndex);
+                                _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex);
+                            }
+                        }
+                    }
+                    if (Sortable.active) {
+                        if (newIndex === null || newIndex === -1) {
+                            newIndex = oldIndex;
+                        }
+                        _dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex);
+                        this.save();
+                    }
+                }
+            }
+            this._nulling();
+        },
+        _nulling: function () {
+            rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = scrollEl = scrollParentEl = tapEvt = touchEvt = moved = newIndex = lastEl = lastCSS = activeGroup = Sortable.active = null;
+        },
+        handleEvent: function (evt) {
+            var type = evt.type;
+            if (type === 'dragover' || type === 'dragenter') {
+                if (dragEl) {
+                    this._onDragOver(evt);
+                    _globalDragOver(evt);
+                }
+            } else if (type === 'drop' || type === 'dragend') {
+                this._onDrop(evt);
+            }
+        },
+        toArray: function () {
+            var order = [], el, children = this.el.children, i = 0, n = children.length, options = this.options;
+            for (; i < n; i++) {
+                el = children[i];
+                if (_closest(el, options.draggable, this.el)) {
+                    order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
+                }
+            }
+            return order;
+        },
+        sort: function (order) {
+            var items = {}, rootEl = this.el;
+            this.toArray().forEach(function (id, i) {
+                var el = rootEl.children[i];
+                if (_closest(el, this.options.draggable, rootEl)) {
+                    items[id] = el;
+                }
+            }, this);
+            order.forEach(function (id) {
+                if (items[id]) {
+                    rootEl.removeChild(items[id]);
+                    rootEl.appendChild(items[id]);
+                }
+            });
+        },
+        save: function () {
+            var store = this.options.store;
+            store && store.set(this);
+        },
+        closest: function (el, selector) {
+            return _closest(el, selector || this.options.draggable, this.el);
+        },
+        option: function (name, value) {
+            var options = this.options;
+            if (value === void 0) {
+                return options[name];
+            } else {
+                options[name] = value;
+                if (name === 'group') {
+                    _prepareGroup(options);
+                }
+            }
+        },
+        destroy: function () {
+            var el = this.el;
+            el[expando] = null;
+            _off(el, 'mousedown', this._onTapStart);
+            _off(el, 'touchstart', this._onTapStart);
+            if (this.nativeDraggable) {
+                _off(el, 'dragover', this);
+                _off(el, 'dragenter', this);
+            }
+            Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) {
+                el.removeAttribute('draggable');
+            });
+            touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1);
+            this._onDrop();
+            this.el = el = null;
+        }
+    };
+    function _cloneHide(state) {
+        if (cloneEl && cloneEl.state !== state) {
+            _css(cloneEl, 'display', state ? 'none' : '');
+            !state && cloneEl.state && rootEl.insertBefore(cloneEl, dragEl);
+            cloneEl.state = state;
+        }
+    }
+    function _closest(el, selector, ctx) {
+        if (el) {
+            ctx = ctx || document;
+            do {
+                if (selector === '>*' && el.parentNode === ctx || _matches(el, selector)) {
+                    return el;
+                }
+            } while (el !== ctx && (el = el.parentNode));
+        }
+        return null;
+    }
+    function _globalDragOver(evt) {
+        if (evt.dataTransfer) {
+            evt.dataTransfer.dropEffect = 'move';
+        }
+        evt.preventDefault();
+    }
+    function _on(el, event, fn) {
+        el.addEventListener(event, fn, false);
+    }
+    function _off(el, event, fn) {
+        el.removeEventListener(event, fn, false);
+    }
+    function _toggleClass(el, name, state) {
+        if (el) {
+            if (el.classList) {
+                el.classList[state ? 'add' : 'remove'](name);
+            } else {
+                var className = (' ' + el.className + ' ').replace(RSPACE, ' ').replace(' ' + name + ' ', ' ');
+                el.className = (className + (state ? ' ' + name : '')).replace(RSPACE, ' ');
+            }
+        }
+    }
+    function _css(el, prop, val) {
+        var style = el && el.style;
+        if (style) {
+            if (val === void 0) {
+                if (document.defaultView && document.defaultView.getComputedStyle) {
+                    val = document.defaultView.getComputedStyle(el, '');
+                } else if (el.currentStyle) {
+                    val = el.currentStyle;
+                }
+                return prop === void 0 ? val : val[prop];
+            } else {
+                if (!(prop in style)) {
+                    prop = '-webkit-' + prop;
+                }
+                style[prop] = val + (typeof val === 'string' ? '' : 'px');
+            }
+        }
+    }
+    function _find(ctx, tagName, iterator) {
+        if (ctx) {
+            var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length;
+            if (iterator) {
+                for (; i < n; i++) {
+                    iterator(list[i], i);
+                }
+            }
+            return list;
+        }
+        return [];
+    }
+    function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) {
+        var evt = document.createEvent('Event'), options = (sortable || rootEl[expando]).options, onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1);
+        evt.initEvent(name, true, true);
+        evt.to = rootEl;
+        evt.from = fromEl || rootEl;
+        evt.item = targetEl || rootEl;
+        evt.clone = cloneEl;
+        evt.oldIndex = startIndex;
+        evt.newIndex = newIndex;
+        rootEl.dispatchEvent(evt);
+        if (options[onName]) {
+            options[onName].call(sortable, evt);
+        }
+    }
+    function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect) {
+        var evt, sortable = fromEl[expando], onMoveFn = sortable.options.onMove, retVal;
+        evt = document.createEvent('Event');
+        evt.initEvent('move', true, true);
+        evt.to = toEl;
+        evt.from = fromEl;
+        evt.dragged = dragEl;
+        evt.draggedRect = dragRect;
+        evt.related = targetEl || toEl;
+        evt.relatedRect = targetRect || toEl.getBoundingClientRect();
+        fromEl.dispatchEvent(evt);
+        if (onMoveFn) {
+            retVal = onMoveFn.call(sortable, evt);
+        }
+        return retVal;
+    }
+    function _disableDraggable(el) {
+        el.draggable = false;
+    }
+    function _unsilent() {
+        _silent = false;
+    }
+    function _ghostIsLast(el, evt) {
+        var lastEl = el.lastElementChild, rect = lastEl.getBoundingClientRect();
+        return (evt.clientY - (rect.top + rect.height) > 5 || evt.clientX - (rect.right + rect.width) > 5) && lastEl;
+    }
+    function _generateId(el) {
+        var str = el.tagName + el.className + el.src + el.href + el.textContent, i = str.length, sum = 0;
+        while (i--) {
+            sum += str.charCodeAt(i);
+        }
+        return sum.toString(36);
+    }
+    function _index(el, selector) {
+        var index = 0;
+        if (!el || !el.parentNode) {
+            return -1;
+        }
+        while (el && (el = el.previousElementSibling)) {
+            if (el.nodeName.toUpperCase() !== 'TEMPLATE' && _matches(el, selector)) {
+                index++;
+            }
+        }
+        return index;
+    }
+    function _matches(el, selector) {
+        if (el) {
+            selector = selector.split('.');
+            var tag = selector.shift().toUpperCase(), re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g');
+            return (tag === '' || el.nodeName.toUpperCase() == tag) && (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length);
+        }
+        return false;
+    }
+    function _throttle(callback, ms) {
+        var args, _this;
+        return function () {
+            if (args === void 0) {
+                args = arguments;
+                _this = this;
+                setTimeout(function () {
+                    if (args.length === 1) {
+                        callback.call(_this, args[0]);
+                    } else {
+                        callback.apply(_this, args);
+                    }
+                    args = void 0;
+                }, ms);
+            }
+        };
+    }
+    function _extend(dst, src) {
+        if (dst && src) {
+            for (var key in src) {
+                if (src.hasOwnProperty(key)) {
+                    dst[key] = src[key];
+                }
+            }
+        }
+        return dst;
+    }
+    Sortable.utils = {
+        on: _on,
+        off: _off,
+        css: _css,
+        find: _find,
+        is: function (el, selector) {
+            return !!_closest(el, selector, el);
+        },
+        extend: _extend,
+        throttle: _throttle,
+        closest: _closest,
+        toggleClass: _toggleClass,
+        index: _index
+    };
+    Sortable.create = function (el, options) {
+        return new Sortable(el, options);
+    };
+    Sortable.version = '1.4.2';
+    return Sortable;
+}));
+CommonControlsLayerSwitcherDOM = function (Sortable) {
+    var LayerSwitcherDOM = {
+        _createDraggableElement: function (elementDraggable, context) {
+            Sortable.create(elementDraggable, {
+                handle: '.GPlayerName',
+                draggable: '.draggable-layer',
+                ghostClass: 'GPghostLayer',
+                animation: 200,
+                onEnd: function (e) {
+                    context._onDragAndDropLayerClick(e);
+                }
+            });
+        },
+        _addUID: function (id) {
+            var uid = this._uid ? id + '-' + this._uid : id;
+            return uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPlayerSwitcher');
+            container.className = 'GPwidget';
+            return container;
+        },
+        _createMainLayersShowElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowLayersList');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createMainLayersElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPlayersList');
+            div.className = 'GPpanel';
+            return div;
+        },
+        _createMainPictoElement: function () {
+            var self = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowLayersListPicto');
+            label.className = 'GPshowAdvancedToolPicto';
+            label.htmlFor = this._addUID('GPshowLayersList');
+            label.title = 'Afficher/masquer le gestionnaire de couches';
+            var spanOpen = document.createElement('span');
+            spanOpen.id = this._addUID('GPshowLayersListOpen');
+            spanOpen.className = 'GPshowAdvancedToolOpen';
+            spanOpen.addEventListener('click', function () {
+                if (document.getElementById(self._addUID('GPshowLayersList')).checked) {
+                    var layers = document.getElementsByClassName('GPlayerInfoOpened');
+                    for (var i = 0; i < layers.length; i++) {
+                        layers[i].className = 'GPlayerInfo';
+                    }
+                    document.getElementById(self._addUID('GPlayerInfoPanel')).className = 'GPlayerInfoPanelClosed';
+                }
+            });
+            label.appendChild(spanOpen);
+            var spanClose = document.createElement('span');
+            spanClose.addEventListener('click', function () {
+                if (document.getElementById(self._addUID('GPshowLayersList')).checked) {
+                    var layers = document.getElementsByClassName('GPlayerInfoOpened');
+                    for (var i = 0; i < layers.length; i++) {
+                        layers[i].className = 'GPlayerInfo';
+                    }
+                    document.getElementById(self._addUID('GPlayerInfoPanel')).className = 'GPlayerInfoPanelClosed';
+                }
+            });
+            spanClose.id = self._addUID('GPshowLayersListClose');
+            label.appendChild(spanClose);
+            return label;
+        },
+        _createMainInfoElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPlayerInfoPanel');
+            div.className = 'GPpanel GPlayerInfoPanelClosed';
+            return div;
+        },
+        _createContainerLayerElement: function (obj) {
+            var container = document.createElement('div');
+            container.id = 'GPlayerSwitcher_ID' + obj.id;
+            container.className = 'GPlayerSwitcher_layer draggable-layer';
+            container.appendChild(this._createBasicToolElement(obj));
+            var array = this._createAdvancedToolShowElement(obj);
+            for (var i = 0; i < array.length; i++) {
+                container.appendChild(array[i]);
+            }
+            container.appendChild(this._createAdvancedToolElement(obj));
+            return container;
+        },
+        _createBasicToolElement: function (obj) {
+            var div = document.createElement('div');
+            div.id = 'GPbasicTools_IDLayer' + obj.id;
+            div.className = 'GPlayerBasicTools';
+            div.appendChild(this._createBasicToolNameElement(obj));
+            var array = this._createBasicToolVisibilityElement(obj);
+            for (var i = 0; i < array.length; i++) {
+                div.appendChild(array[i]);
+            }
+            return div;
+        },
+        _createBasicToolNameElement: function (obj) {
+            var span = document.createElement('span');
+            span.id = 'GPname_ID' + obj.id;
+            span.className = 'GPlayerName';
+            span.title = obj.description || obj.title;
+            span.innerHTML = obj.title;
+            return span;
+        },
+        _createBasicToolVisibilityElement: function (obj) {
+            var list = [];
+            var checked = obj.visibility;
+            var id = 'GPvisibility_ID' + obj.id;
+            var input = document.createElement('input');
+            input.id = id;
+            input.type = 'checkbox';
+            input.checked = checked;
+            var label = document.createElement('label');
+            label.htmlFor = id;
+            label.id = 'GPvisibilityPicto_ID' + obj.id;
+            label.className = 'GPlayerVisibility';
+            label.title = 'Afficher/masquer la couche';
+            var context = this;
+            if (input.addEventListener) {
+                input.addEventListener('click', function (e) {
+                    context._onVisibilityLayerClick.call(context, e);
+                });
+            } else if (input.attachEvent) {
+                input.attachEvent('onclick', function (e) {
+                    context._onVisibilityLayerClick.call(context, e);
+                });
+            }
+            list.push(input);
+            list.push(label);
+            return list;
+        },
+        _createAdvancedToolShowElement: function (obj) {
+            var list = [];
+            var label = document.createElement('label');
+            label.id = 'GPshowAdvancedToolsPicto_ID' + obj.id;
+            label.htmlFor = 'GPshowAdvancedTools_ID' + obj.id;
+            label.title = 'Plus d\'outils';
+            label.className = 'GPshowMoreOptions GPshowLayerAdvancedTools';
+            var input = document.createElement('input');
+            input.type = 'checkbox';
+            input.id = 'GPshowAdvancedTools_ID' + obj.id;
+            list.push(input);
+            list.push(label);
+            return list;
+        },
+        _createAdvancedToolElement: function (obj) {
+            var container = document.createElement('div');
+            container.id = 'GPadvancedTools_ID' + obj.id;
+            container.className = 'GPlayerAdvancedTools';
+            container.appendChild(this._createAdvancedToolDeleteElement(obj));
+            if (obj.title && obj.description) {
+                container.appendChild(this._createAdvancedToolInformationElement(obj));
+            }
+            if (obj.type !== 'feature') {
+                var array = this._createAdvancedToolOpacityElement(obj);
+                for (var i = 0; i < array.length; i++) {
+                    container.appendChild(array[i]);
+                }
+            }
+            return container;
+        },
+        _createAdvancedToolDeleteElement: function (obj) {
+            var div = document.createElement('div');
+            div.id = 'GPremove_ID' + obj.id;
+            div.className = 'GPlayerRemove';
+            div.title = 'Supprimer la couche';
+            div.layerId = obj.id;
+            var context = this;
+            if (div.addEventListener) {
+                div.addEventListener('click', function (e) {
+                    context._onDropLayerClick.call(context, e);
+                });
+            } else if (div.attachEvent) {
+                div.attachEvent('onclick', function (e) {
+                    context._onDropLayerClick.call(context, e);
+                });
+            }
+            return div;
+        },
+        _createAdvancedToolInformationElement: function (obj) {
+            var div = document.createElement('div');
+            div.id = 'GPinfo_ID' + obj.id;
+            div.className = 'GPlayerInfo';
+            div.title = 'Informations/légende';
+            div.layerId = obj.id;
+            var context = this;
+            if (div.addEventListener) {
+                div.addEventListener('click', function (e) {
+                    context._onOpenLayerInfoClick.call(context, e);
+                });
+            } else if (div.attachEvent) {
+                div.attachEvent('onclick', function (e) {
+                    context._onOpenLayerInfoClick.call(context, e);
+                });
+            }
+            return div;
+        },
+        _createAdvancedToolOpacityElement: function (obj) {
+            var list = [];
+            var divO = document.createElement('div');
+            divO.id = 'GPopacity_ID' + obj.id;
+            divO.className = 'GPlayerOpacity';
+            divO.title = 'Opacité';
+            var opacity = Math.round(obj.opacity * 100);
+            var input = document.createElement('input');
+            input.id = 'GPopacityValueDiv_ID' + obj.id;
+            input.type = 'range';
+            input.value = opacity;
+            var context = this;
+            if (input.addEventListener) {
+                input.addEventListener('change', function (e) {
+                    context._onChangeLayerOpacity.call(context, e);
+                });
+            } else if (input.attachEvent) {
+                input.attachEvent('onchange', function (e) {
+                    context._onChangeLayerOpacity.call(context, e);
+                });
+            }
+            if (input.addEventListener) {
+                input.addEventListener('input', function (e) {
+                    context._onChangeLayerOpacity.call(context, e);
+                });
+            } else if (input.attachEvent) {
+                input.attachEvent('oninput', function (e) {
+                    context._onChangeLayerOpacity.call(context, e);
+                });
+            }
+            divO.appendChild(input);
+            var divC = document.createElement('div');
+            divC.id = 'GPopacityValueDiv_ID' + obj.id;
+            divC.className = 'GPlayerOpacityValue';
+            var span = document.createElement('span');
+            span.id = 'GPopacityValue_ID' + obj.id;
+            span.innerHTML = opacity + '%';
+            divC.appendChild(span);
+            list.push(divO);
+            list.push(divC);
+            return list;
+        },
+        _createContainerLayerInfoElement: function (obj) {
+            var container = document.createElement('div');
+            container.id = 'GPlayerInfoContent';
+            var title = document.createElement('div');
+            title.id = 'GPlayerInfoTitle';
+            title.innerHTML = obj.title;
+            container.appendChild(title);
+            if (obj.quicklookUrl) {
+                var quick = document.createElement('div');
+                quick.id = 'GPlayerInfoQuicklook';
+                quick.title = 'Afficher un aperçu de la couche';
+                var refquick = document.createElement('a');
+                refquick.href = obj.quicklookUrl;
+                refquick.appendChild(quick);
+                container.appendChild(refquick);
+            }
+            var close = document.createElement('div');
+            close.id = 'GPlayerInfoClose';
+            close.title = 'Fermer la fenêtre';
+            var onCloseClick = function () {
+                document.getElementById('GPlayerInfoPanel').className = 'GPlayerInfoPanelClosed';
+                var layers = document.getElementsByClassName('GPlayerInfoOpened');
+                for (var i = 0; i < layers.length; i++) {
+                    layers[i].className = 'GPlayerInfo';
+                }
+            };
+            if (close.addEventListener) {
+                close.addEventListener('click', onCloseClick);
+            } else if (close.attachEvent) {
+                close.attachEvent('onclick', onCloseClick);
+            }
+            container.appendChild(close);
+            var desc = document.createElement('div');
+            desc.id = 'GPlayerInfoDescription';
+            desc.innerHTML = obj.description;
+            container.appendChild(desc);
+            if (obj.metadata) {
+                var mtd = document.createElement('div');
+                mtd.id = 'GPlayerInfoMetadata';
+                var mtdtitle = document.createElement('div');
+                mtdtitle.className = 'GPlayerInfoSubtitle';
+                mtdtitle.innerHTML = 'Métadonnées';
+                mtd.appendChild(mtdtitle);
+                for (var i = 0; i < obj.metadata.length; i++) {
+                    var urlmtd = obj.metadata[i].url;
+                    var mtdlink = document.createElement('div');
+                    mtdlink.className = 'GPlayerInfoLink';
+                    var refmtd = document.createElement('a');
+                    refmtd.href = urlmtd;
+                    refmtd.innerHTML = urlmtd;
+                    mtdlink.appendChild(refmtd);
+                    mtd.appendChild(mtdlink);
+                }
+                if (obj.metadata.length !== 0) {
+                    container.appendChild(mtd);
+                }
+            }
+            if (obj.legends) {
+                var lgd = document.createElement('div');
+                lgd.id = 'GPlayerInfoLegend';
+                var lgdtitle = document.createElement('div');
+                lgdtitle.className = 'GPlayerInfoSubtitle';
+                lgdtitle.innerHTML = 'Légende';
+                lgd.appendChild(lgdtitle);
+                var legends = {};
+                var maxScale = obj.maxScaleDenominator || 560000000;
+                for (var k = 0; k < obj.legends.length; k++) {
+                    var minScale = obj.legends[k].minScaleDenominator;
+                    if (minScale) {
+                        var s = minScale.toString();
+                        minScale = Math.round(parseInt(s.substring(0, 3), 10) / 10) * Math.pow(10, s.length - 2);
+                    } else {
+                        minScale = 270;
+                    }
+                    legends[minScale] = obj.legends[k];
+                }
+                for (var scale in legends) {
+                    if (legends.hasOwnProperty(scale)) {
+                        var urllgd = legends[scale].url;
+                        if (typeof urllgd === 'string' && urllgd.toLowerCase().indexOf('nolegend.jpg') == -1) {
+                            var lgdlink = document.createElement('div');
+                            lgdlink.className = 'GPlayerInfoLink';
+                            maxScale = legends[scale].maxScaleDenominator || maxScale;
+                            var reflgd = document.createElement('a');
+                            reflgd.href = urllgd;
+                            reflgd.innerHTML = 'Du 1/' + scale + ' au 1/' + maxScale;
+                            lgdlink.appendChild(reflgd);
+                            lgd.appendChild(lgdlink);
+                        } else {
+                            delete legends[scale];
+                        }
+                    }
+                }
+                if (Object.keys(legends).length !== 0) {
+                    container.appendChild(lgd);
+                }
+            }
+            return container;
+        }
+    };
+    return LayerSwitcherDOM;
+}(sortable);
+LeafletControlsLayerSwitcher = function (L, woodman, LayerSwitcherDOM) {
+    var LayerSwitcher = L.Control.Layers.extend({
+        includes: LayerSwitcherDOM,
+        options: {
+            collapsed: true,
+            position: 'topright',
+            autoZIndex: true,
+            layers: []
+        },
+        initialize: function (options) {
+            L.Util.setOptions(this, options);
+            this._hasLayersConfig = !this.options.layers || Object.keys(this.options.layers).length === 0 ? false : true;
+            this._layersConfig = this._hasLayersConfig ? this.options.layers : [];
+            this._layers = {};
+            this._lastZIndex = 0;
+            if (this._hasLayersConfig) {
+                for (var i = 0; i < this._layersConfig.length; i++) {
+                    var obj = this._layersConfig[i];
+                    this._addLayer(obj.layer, null, true);
+                }
+            }
+        },
+        onAdd: function (map) {
+            var layersMap = map._layers;
+            if (Object.keys(layersMap).length !== 0) {
+                var layersKeys = Object.keys(layersMap);
+                this._lastZIndex = 0;
+                for (var i = 0; i < layersKeys.length; i++) {
+                    var layerId = layersKeys[i];
+                    if (this.options.autoZIndex && layersMap[layerId].setZIndex) {
+                        this._lastZIndex++;
+                        layersMap[layerId].setZIndex(this._lastZIndex);
+                    }
+                    if (this._hasLayersConfig) {
+                        if (this._layers[layerId]) {
+                            continue;
+                        }
+                    }
+                    this.addOverlay(layersMap[layerId]);
+                }
+            }
+            if (Object.keys(layersMap).length === 0) {
+                var config = this._layersConfig;
+                this._lastZIndex = 0;
+                for (var j = 0; j < config.length; j++) {
+                    var layer = config[j].layer;
+                    if (!map.hasLayer(layer)) {
+                        map.addLayer(layer);
+                        this.addOverlay(layer, null);
+                        if (this.options.autoZIndex && layer.setZIndex) {
+                            this._lastZIndex++;
+                            layer.setZIndex(this._lastZIndex);
+                        }
+                    }
+                }
+            }
+            for (var k in this._layers) {
+                if (this._layers.hasOwnProperty(k)) {
+                    var obj = this._layers[k];
+                    if (!obj.visibility) {
+                        this._visibilityLayer(!obj.visibility, obj.layer);
+                    }
+                }
+            }
+            this._initLayout();
+            this._update();
+            map.on('layeradd', this._onLayerChange, this);
+            map.on('layerremove', this._onLayerChange, this);
+            return this._container;
+        },
+        _addLayer: function (layer, name, overlay) {
+            var id = layer._geoportal_id ? layer._geoportal_id : layer._leaflet_id;
+            if (!id) {
+                return;
+            }
+            var layerConfig = {};
+            for (var i in this._layersConfig) {
+                if (this._layersConfig.hasOwnProperty(i)) {
+                    if (id === L.stamp(this._layersConfig[i].layer)) {
+                        layerConfig = this._layersConfig[i].config;
+                        var display = typeof this._layersConfig[i].display != 'undefined' ? this._layersConfig[i].display : true;
+                        if (!display) {
+                            return;
+                        }
+                        break;
+                    }
+                }
+            }
+            this._layers[id] = {
+                layer: layer,
+                id: id,
+                overlay: overlay,
+                title: layer._geoportal_id && layer._title ? layer._title : name ? name : id,
+                description: layer._geoportal_id && layer._description ? layer._description : name ? name : id,
+                visibility: layer._geoportal_id ? layer.getVisible() : true,
+                legends: layer._geoportal_id ? layer._legends : null,
+                metadata: layer._geoportal_id ? layer._metadata : null,
+                quicklookUrl: layer._geoportal_id ? layer._quicklookUrl : null
+            };
+            if (layerConfig && Object.keys(layerConfig)) {
+                L.Util.extend(this._layers[id], layerConfig);
+            }
+            layer._geoportal_id ? layer.setVisible(this._layers[id].visibility) : null;
+        },
+        _initLayout: function () {
+            var container = this._container = this._createMainContainerElement();
+            var input = this._createMainLayersShowElement();
+            container.appendChild(input);
+            if (!this.options.collapsed) {
+                input.checked = 'checked';
+            }
+            var divL = this._overlaysList = this._createMainLayersElement();
+            container.appendChild(divL);
+            var picto = this._createMainPictoElement();
+            container.appendChild(picto);
+            var divI = this._createMainInfoElement();
+            container.appendChild(divI);
+            this._createDraggableElement(this._overlaysList, this);
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            this._map.on('moveend', this._onOutOfRangeLayerZoom, this);
+            switch (this.getPosition()) {
+            case 'topright':
+                container.style.position = 'relative';
+                container.style.top = '0';
+                container.style.right = '0';
+                break;
+            case 'topleft':
+                container.style.position = 'relative';
+                container.style.top = '0';
+                container.style.right = 'initial';
+                picto.style.float = 'left';
+                divL.style.borderBottomRightRadius = '5px';
+                divL.style.borderBottomLeftRadius = '0';
+                divI.style.right = 'initial';
+                divI.style.left = '190px';
+                break;
+            case 'bottomleft':
+                container.style.position = 'relative';
+                container.style.top = '0';
+                container.style.right = 'initial';
+                picto.style.float = 'left';
+                divL.style.borderBottomRightRadius = '5px';
+                divL.style.borderBottomLeftRadius = '0';
+                divI.style.right = 'initial';
+                divI.style.left = '190px';
+                break;
+            case 'bottomright':
+                container.style.position = 'relative';
+                container.style.top = '0';
+                container.style.right = '0';
+                break;
+            default:
+                container.style.position = 'relative';
+                container.style.top = '0';
+                container.style.right = '0';
+            }
+        },
+        _update: function () {
+            if (!this._container) {
+                return;
+            }
+            this._overlaysList.innerHTML = '';
+            var layersId = [];
+            for (var i in this._layers) {
+                if (this._layers.hasOwnProperty(i)) {
+                    layersId.push(i);
+                }
+            }
+            var layers = layersId.sort(function (a, b) {
+                var ia = parseInt(a, 10);
+                var ib = parseInt(b, 10);
+                return ia - ib;
+            }).reverse();
+            for (var j = 0; j < layers.length; j++) {
+                var id = layers[j];
+                var obj = this._layers[id];
+                this._addItem(obj);
+            }
+        },
+        _addItem: function (obj) {
+            obj.opacity = obj.layer.options.opacity;
+            var container = this._createContainerLayerElement(obj);
+            obj.layer.options.minZoom > this._map.getZoom() || obj.layer.options.maxZoom < this._map.getZoom() ? L.DomUtil.addClass(container, 'outOfRange') : L.DomUtil.removeClass(container, 'outOfRange');
+            this._overlaysList.appendChild(container);
+            return container;
+        },
+        _onLayerChange: function (e) {
+            var obj = this._layers[L.stamp(e.layer)];
+            if (!obj) {
+                return;
+            }
+            if (!this._handlingClick) {
+                this._update();
+            }
+            var type = e.type === 'layeradd' ? 'overlayadd' : 'overlayremove';
+            if (type) {
+                this._map.fire(type, obj);
+            }
+        },
+        removeLayer: function (layer) {
+            var id = L.stamp(layer);
+            delete this._layers[id];
+            this._update();
+            return this;
+        },
+        _visibilityLayer: function (checked, layer) {
+            this._handlingClick = true;
+            if (layer._geoportal_id) {
+                var value = !layer.getVisible();
+                layer.setVisible(value);
+            }
+            if (checked && this._map.hasLayer(layer)) {
+                this._map.removeLayer(layer);
+            } else if (!checked && !this._map.hasLayer(layer)) {
+                this._map.addLayer(layer);
+            } else {
+            }
+            this._handlingClick = false;
+            this._refocusOnMap();
+        },
+        _onOutOfRangeLayerZoom: function () {
+            var map = this._map;
+            var layers = this._layers;
+            for (var i in layers) {
+                if (layers.hasOwnProperty(i)) {
+                    var layer = layers[i].layer;
+                    var id = layers[i].id;
+                    var div = L.DomUtil.get('GPlayerSwitcher_ID' + id);
+                    if (layer.options.minZoom > map.getZoom() || layer.options.maxZoom < map.getZoom()) {
+                        L.DomUtil.addClass(div, 'outOfRange');
+                    } else {
+                        L.DomUtil.removeClass(div, 'outOfRange');
+                    }
+                }
+            }
+        },
+        _onVisibilityLayerClick: function (e) {
+            var layerId = e.target.id;
+            var layerIdx = layerId.substring(layerId.indexOf('_') + 3);
+            var input = L.DomUtil.get(layerId);
+            this._layers[layerIdx].visibility = input.checked;
+            this._visibilityLayer(!input.checked, this._layers[layerIdx].layer);
+        },
+        _onDropLayerClick: function (e) {
+            var layerId = e.target.id;
+            var layerIdx = layerId.substring(layerId.indexOf('_') + 3);
+            var layer = this._layers[layerIdx].layer;
+            this.removeLayer(layer);
+            if (this._map.hasLayer(layer)) {
+                this._map.removeLayer(layer);
+            }
+        },
+        _onChangeLayerOpacity: function (e) {
+            var layerId = e.target.id;
+            var layerIdx = layerId.substring(layerId.indexOf('_') + 3);
+            var layer = this._layers[layerIdx].layer;
+            var opacityValue = e.target.value;
+            var opacityId = L.DomUtil.get('GPopacityValue_ID' + layerIdx);
+            opacityId.innerHTML = opacityValue + '%';
+            if (this._map.hasLayer(layer)) {
+                layer.setOpacity(opacityValue / 100);
+            }
+        },
+        _onOpenLayerInfoClick: function (e) {
+            var layerId = e.target.id;
+            var layerIdx = layerId.substring(layerId.indexOf('_') + 3);
+            var layer = this._layers[layerIdx];
+            var divId = L.DomUtil.get(e.target.id);
+            var panel = null;
+            var info = null;
+            if (divId.className === 'GPlayerInfoOpened') {
+                L.DomUtil.removeClass(divId, 'GPlayerInfoOpened');
+                L.DomUtil.addClass(divId, 'GPlayerInfo');
+                panel = L.DomUtil.get('GPlayerInfoPanel');
+                L.DomUtil.removeClass(panel, 'GPpanel');
+                L.DomUtil.removeClass(panel, 'GPlayerInfoPanelOpened');
+                L.DomUtil.addClass(panel, 'GPlayerInfoPanelClosed');
+                info = L.DomUtil.get('GPlayerInfoContent');
+                panel.removeChild(info);
+                return;
+            }
+            var layers = document.getElementsByClassName('GPlayerInfoOpened');
+            for (var i = 0; i < layers.length; i++) {
+                layers[i].className = 'GPlayerInfo';
+            }
+            L.DomUtil.removeClass(divId, 'GPlayerInfo');
+            L.DomUtil.addClass(divId, 'GPlayerInfoOpened');
+            panel = L.DomUtil.get('GPlayerInfoPanel');
+            L.DomUtil.addClass(panel, 'GPpanel');
+            L.DomUtil.removeClass(panel, 'GPlayerInfoPanelClosed');
+            L.DomUtil.addClass(panel, 'GPlayerInfoPanelOpened');
+            info = L.DomUtil.get('GPlayerInfoContent');
+            if (info) {
+                panel.removeChild(info);
+            }
+            var infoLayer = this._createContainerLayerInfoElement(layer);
+            panel.appendChild(infoLayer);
+        },
+        _onDragAndDropLayerClick: function (e) {
+            var layerId = e.item.id;
+            var layerIdx = layerId.substring(layerId.indexOf('_') + 3);
+            var layer = this._layers[layerIdx].layer;
+            var matchesLayers = document.querySelectorAll('div.GPlayerSwitcher_layer');
+            this._lastZIndex = matchesLayers.length;
+            for (var i = 0; i < matchesLayers.length; i++) {
+                var tag = matchesLayers[i].id;
+                var id = tag.substring(tag.indexOf('_') + 3);
+                var _layer = this._layers[id].layer;
+                if (this.options.autoZIndex && _layer.setZIndex) {
+                    this._lastZIndex--;
+                    _layer.setZIndex(this._lastZIndex);
+                }
+            }
+        },
+        addLayer: function (layer, config) {
+            var map = this._map;
+            var cfg = this._layersConfig;
+            if (!layer) {
+                console.log('[ERROR] LayerSwitcher:addLayer - missing layer parameter !');
+                return;
+            }
+            if (!map.hasLayer(layer)) {
+                console.log('[WARN] LayerSwitcher:addLayer - layer has not been added on map !');
+            }
+            var id = L.stamp(layer);
+            for (var i in cfg) {
+                if (cfg.hasOwnProperty(i)) {
+                    if (id === L.stamp(cfg[i].layer)) {
+                        delete cfg[i];
+                        break;
+                    }
+                }
+            }
+            var _config = config || {};
+            L.Util.extend(_config, { layer: layer });
+            cfg.push(_config);
+            layer.setZIndex(this._lastZIndex++);
+            this.addOverlay(layer);
+            this._update();
+        }
+    });
+    return LayerSwitcher;
+}(leaflet, {}, CommonControlsLayerSwitcherDOM);
+CommonUtilsConfig = function () {
+    var Config = {
+        configuration: null,
+        isConfigLoaded: function () {
+            var scope = typeof window !== 'undefined' ? window : {};
+            if (scope.Gp && scope.Gp.Config && Object.keys(scope.Gp.Config).length !== 0) {
+                this.configuration = scope.Gp.Config;
+                return true;
+            }
+            return false;
+        },
+        getLayerId: function (layerName, service) {
+            var layerId = null;
+            if (this.configuration) {
+                var layers = this.configuration['layers'];
+                for (var key in layers) {
+                    if (layers.hasOwnProperty(key)) {
+                        var parts = key.split('$');
+                        if (layerName === parts[0]) {
+                            if (parts[1]) {
+                                var servicePartsLayer = parts[1].split(':');
+                                var servicePartsService = parts[1].split(';');
+                                if (servicePartsService[1] === service) {
+                                    layerId = key;
+                                    break;
+                                }
+                                if (servicePartsLayer[2] === service) {
+                                    layerId = key;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            if (!layerId) {
+                console.log('ERROR layer id (' + layerName + ' / ' + service + ') was not found !?');
+            }
+            return layerId;
+        },
+        getLayerParams: function (layerName, service, apiKey) {
+            var params = {};
+            if (this.configuration) {
+                var layerId = this.getLayerId(layerName, service);
+                if (layerId) {
+                    var layerConf = this.configuration.layers[layerId];
+                    var key = layerConf.apiKeys[0];
+                    if (apiKey) {
+                        if (apiKey !== key) {
+                            console.log('ERROR different keys (' + apiKey + ' !== ' + key + ') !?');
+                            return;
+                        }
+                    }
+                    apiKey = apiKey || key;
+                    params.key = apiKey;
+                    params.url = layerConf.getServerUrl(apiKey);
+                    params.version = layerConf.getServiceParams().version;
+                    params.styles = layerConf.getDefaultStyle();
+                    params.format = layerConf.getDefaultFormat();
+                    params.projection = layerConf.getDefaultProjection();
+                    params.minScale = layerConf.getMinScaleDenominator();
+                    params.maxScale = layerConf.getMaxScaleDenominator();
+                    params.extent = layerConf.getBBOX();
+                    params.legends = layerConf.getLegends();
+                    params.metadata = layerConf.getMetadata();
+                    params.originators = layerConf.getOriginators();
+                    params.title = layerConf.getTitle();
+                    params.description = layerConf.getDescription();
+                    params.quicklookUrl = layerConf.getQuicklookUrl();
+                    if (layerConf.wmtsOptions) {
+                        params.tileMatrixSetLimits = layerConf.wmtsOptions.tileMatrixSetLimits;
+                    }
+                    var TMSLink = layerConf.getTMSID();
+                    if (TMSLink) {
+                        params.TMSLink = TMSLink;
+                        var tmsConf = this.configuration.getTMSConf(TMSLink);
+                        params.matrixOrigin = tmsConf.getTopLeftCorner();
+                        params.nativeResolutions = tmsConf.nativeResolutions;
+                        params.matrixIds = tmsConf.matrixIds;
+                        params.tileMatrices = tmsConf.tileMatrices;
+                    }
+                }
+            }
+            return params;
+        },
+        getServiceParams: function (resource, service, apiKey) {
+            var params = {};
+            if (this.configuration) {
+                var layerId = this.getLayerId(resource, service);
+                if (layerId) {
+                    var layerConf = this.configuration.layers[layerId];
+                    var key = layerConf.apiKeys[0];
+                    if (apiKey) {
+                        if (apiKey !== key) {
+                            return;
+                        }
+                    }
+                    apiKey = apiKey || key;
+                    params.key = apiKey;
+                    params.url = layerConf.getServerUrl(apiKey);
+                    params.version = layerConf.getServiceParams().version;
+                    params.extent = layerConf.getBBOX();
+                    params.title = layerConf.getTitle();
+                    params.description = layerConf.getDescription();
+                }
+            }
+            return params;
+        },
+        getResolutions: function () {
+            var resolutions = [];
+            if (this.configuration) {
+                resolutions = this.configuration['generalOptions']['wgs84Resolutions'];
+            }
+            return resolutions;
+        },
+        getTileMatrix: function (tmsName) {
+            var tms = {};
+            if (this.configuration) {
+                if (tmsName) {
+                    tms = this.configuration['tileMatrixSets'][tmsName.toUpperCase()];
+                }
+            }
+            return tms;
+        },
+        getGlobalConstraints: function (layerId) {
+            var params = {};
+            if (layerId) {
+                var layerConf = this.configuration.layers[layerId];
+                params.projection = layerConf.getDefaultProjection();
+                params.minScale = layerConf.getMinScaleDenominator();
+                params.maxScale = layerConf.getMaxScaleDenominator();
+                params.extent = layerConf.getBBOX();
+            }
+            return params;
+        }
+    };
+    return Config;
+}();
+CommonUtilsCheckRightManagement = function (woodman, Config) {
+    return {
+        check: function (options) {
+            if (!options) {
+                return;
+            }
+            var _key = options.key;
+            var _resources = options.resources || [];
+            var _services = options.services || [];
+            if (!_resources || _resources.length === 0) {
+                return;
+            }
+            if (!_services || _services.length === 0) {
+                return;
+            }
+            var _rightManagement = {};
+            if (!_key) {
+                if (!Config.isConfigLoaded()) {
+                    console.log('WARNING : ' + 'parameter \'apiKey\' has not been parametered, ' + 'and the contract key configuration has not been loaded, ' + 'so impossible to check yours rights !');
+                    return;
+                } else {
+                    _key = Object.keys(Config.configuration.generalOptions.apiKeys)[0];
+                }
+            }
+            if (_key) {
+                if (!Config.isConfigLoaded()) {
+                    console.log('WARNING : ' + 'the contract key configuration has not been loaded, ' + 'so be carefull !');
+                    var _noRightManagement = {};
+                    for (var i = 0; i < _services.length; i++) {
+                        var service = _services[i];
+                        _noRightManagement[service] = [];
+                        for (var j = 0; j < _resources.length; j++) {
+                            var resource = _resources[j];
+                            _noRightManagement[service].push(resource);
+                        }
+                    }
+                    _noRightManagement.key = _key;
+                    return _noRightManagement;
+                } else {
+                    for (var k = 0; k < _resources.length; k++) {
+                        var _resource = _resources[k];
+                        for (var l = 0; l < _services.length; l++) {
+                            var _service = _services[l];
+                            var params = Config.getServiceParams(_resource, _service, _key);
+                            if (!params || Object.keys(params).length === 0) {
+                                console.log('WARNING : ' + 'contract key configuration has no rights to load this geoportal ' + 'resource (' + _resource + ') ' + 'for this service (' + _service + ') ');
+                                continue;
+                            }
+                            if (!_rightManagement[_service]) {
+                                _rightManagement[_service] = [];
+                            }
+                            _rightManagement[_service].push(_resource);
+                        }
+                    }
+                    if (!_rightManagement || Object.keys(_rightManagement).length === 0) {
+                        console.log('WARNING : ' + 'the contract key configuration has been loaded, ' + 'and the parameter \'apiKey\' has been parametered, ' + 'but, there is a problem on the mapping between the contract and the key !');
+                        return;
+                    }
+                    _rightManagement.key = _key;
+                    return _rightManagement;
+                }
+            }
+        }
+    };
+}({}, CommonUtilsConfig);
+CommonUtilsSelectorID = function () {
+    var SelectorID = {
+        generate: function () {
+            var timestamp = Math.floor(Date.now());
+            return function () {
+                return timestamp++;
+            };
+        }(),
+        name: function (id) {
+            var name = null;
+            var i = id.indexOf('-');
+            if (i === -1) {
+                name = id;
+            } else {
+                name = id.substring(0, i);
+            }
+            return name;
+        },
+        index: function (id) {
+            var index = null;
+            var name = this.name(id);
+            if (name !== id) {
+                var i = name.indexOf('_');
+                if (i !== -1) {
+                    index = name.substring(i + 1);
+                }
+            }
+            return index;
+        },
+        uuid: function (id) {
+            var uuid = null;
+            var i = id.indexOf('-');
+            if (i !== -1) {
+                uuid = parseInt(id.substring(i + 1), 10);
+            }
+            return uuid;
+        }
+    };
+    return SelectorID;
+}();
+CommonControlsLocationSelectorDOM = function (ID) {
+    var LocationSelectorDOM = {
+        _addUID: function (id) {
+            return id + '-' + this._uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.className = this._addUID('GPlocationPoint');
+            container.className += ' GPwidget';
+            return container;
+        },
+        _createLocationPointElement: function (id, display) {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPlocationPoint_' + id);
+            div.className = display ? 'GPflexInput GPlocationStageFlexInput' : 'GPflexInput GPlocationStageFlexInputHidden';
+            div.style.cssText = '';
+            return div;
+        },
+        _createLocationPointLabelElement: function (id, text) {
+            var self = this;
+            var labelOrigin = document.createElement('label');
+            labelOrigin.id = this._addUID('GPlocationOriginLabel_' + id);
+            labelOrigin.htmlFor = 'GPlocationOrigin_' + id;
+            labelOrigin.innerHTML = text;
+            labelOrigin.addEventListener('click', function (e) {
+                var i = ID.index(this.id);
+                var points = document.getElementsByClassName(self._addUID('GPlocationPoint'));
+                for (var j = 0; j < points.length; j++) {
+                    var tag = points[j].childNodes[0].id;
+                    var id = ID.index(tag);
+                    document.getElementById(self._addUID('GPlocationPoint_' + id)).style.cssText = '';
+                }
+                document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).value = '';
+                document.getElementById(self._addUID('GPlocationOrigin_' + i)).value = '';
+                document.getElementById(self._addUID('GPlocationPoint_' + i)).style.cssText = '';
+                document.getElementById(self._addUID('GPlocationOriginPointer_' + i)).checked = false;
+                document.getElementById(self._addUID('GPlocationOrigin_' + i)).className = 'GPlocationOriginVisible';
+                document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).className = 'GPlocationOriginHidden';
+                if (document.getElementById(self._addUID('GPlocationStageRemove_' + i))) {
+                    document.getElementById(self._addUID('GPlocationStageRemove_' + i)).className = 'GPlocationStageRemove';
+                }
+                if (document.getElementById(self._addUID('GPlocationStageAdd'))) {
+                    document.getElementById(self._addUID('GPlocationStageAdd')).className = '';
+                }
+                self.onLocationClearPointClick(e);
+            });
+            return labelOrigin;
+        },
+        _createLocationAutoCompleteteInputElement: function (id) {
+            var self = this;
+            var inputOrigin = document.createElement('input');
+            inputOrigin.id = this._addUID('GPlocationOrigin_' + id);
+            inputOrigin.className = 'GPlocationOriginVisible';
+            inputOrigin.type = 'text';
+            inputOrigin.placeholder = 'Saisir une adresse';
+            inputOrigin.autocomplete = 'off';
+            inputOrigin.addEventListener('keyup', function (e) {
+                var charCode = e.which || e.keyCode;
+                if (charCode === 13 || charCode === 10 || charCode === 38 || charCode === 40) {
+                    return;
+                }
+                var i = ID.index(this.id);
+                if (document.getElementById(self._addUID('GPlocationOrigin_' + i)).value.length > 2) {
+                    document.getElementById(self._addUID('GPlocationAutoCompleteList_' + i)).style.display = 'block';
+                } else {
+                    document.getElementById(self._addUID('GPlocationAutoCompleteList_' + i)).style.display = 'none';
+                }
+                self.onAutoCompleteSearchText(e);
+            });
+            inputOrigin.addEventListener('keydown', function (e) {
+                var charCode = e.which || e.keyCode;
+                var container = document.getElementById(self._addUID('GPlocationAutoCompleteList_' + id));
+                if (!container) {
+                    return;
+                }
+                var curr = container.getElementsByClassName('GPautoCompleteProposal current');
+                var list = container.getElementsByClassName('GPautoCompleteProposal');
+                var length = list.length;
+                if (!length) {
+                    return;
+                }
+                var current = null;
+                if (!curr.length) {
+                    current = list[0];
+                    current.className = 'GPautoCompleteProposal current';
+                    current.style.color = '#000000';
+                    current.style['background-color'] = '#CEDBEF';
+                    return;
+                } else {
+                    current = curr[0];
+                }
+                var index = parseInt(ID.index(current.id), 10);
+                var next = index === length - 1 ? list[0] : list[index + 1];
+                var prev = index === 0 ? list[length - 1] : list[index - 1];
+                current.style['background-color'] = '';
+                current.style.color = '';
+                prev.style['background-color'] = '';
+                prev.style.color = '';
+                next.style['background-color'] = '';
+                next.style.color = '';
+                switch (charCode) {
+                case 38:
+                    console.log('arrow up');
+                    current.className = 'GPautoCompleteProposal';
+                    prev.className = 'GPautoCompleteProposal current';
+                    prev.style.color = '#000000';
+                    prev.style['background-color'] = '#CEDBEF';
+                    break;
+                case 40:
+                    console.log('arrow down');
+                    current.className = 'GPautoCompleteProposal';
+                    next.className = 'GPautoCompleteProposal current';
+                    next.style.color = '#000000';
+                    next.style['background-color'] = '#CEDBEF';
+                    break;
+                case 13:
+                    console.log('enter');
+                    current.click(e);
+                    break;
+                }
+                current.focus();
+            });
+            return inputOrigin;
+        },
+        _createLocationCoordinateInputElement: function (id) {
+            var self = this;
+            var inputOriginCoord = document.createElement('input');
+            inputOriginCoord.id = this._addUID('GPlocationOriginCoords_' + id);
+            inputOriginCoord.className = 'GPlocationOriginHidden';
+            inputOriginCoord.type = 'text';
+            inputOriginCoord.disabled = false;
+            inputOriginCoord.addEventListener('click', function () {
+                var i = ID.index(this.id);
+                document.getElementById(self._addUID('GPlocationOriginLabel_' + i)).click();
+            });
+            return inputOriginCoord;
+        },
+        _createLocationPointerShowInputElement: function (id) {
+            var inputOriginPointer = document.createElement('input');
+            inputOriginPointer.id = this._addUID('GPlocationOriginPointer_' + id);
+            inputOriginPointer.type = 'checkbox';
+            return inputOriginPointer;
+        },
+        _createLocationPointerInputElement: function (id) {
+            var self = this;
+            var labelOriginPointer = document.createElement('label');
+            labelOriginPointer.id = this._addUID('GPlocationOriginPointerImg_' + id);
+            labelOriginPointer.htmlFor = 'GPlocationOriginPointer_' + id;
+            labelOriginPointer.className = 'GPlocationOriginPointerImg';
+            labelOriginPointer.title = 'Pointer un lieu sur la carte';
+            labelOriginPointer.addEventListener('click', function (e) {
+                e.preventDefault();
+                e.stopPropagation();
+                var i = ID.index(this.id);
+                var points = document.getElementsByClassName(self._addUID('GPlocationPoint'));
+                var j;
+                var tag;
+                var id;
+                for (j = 0; j < points.length; j++) {
+                    tag = points[j].childNodes[0].id;
+                    id = ID.index(tag);
+                    if (i != id) {
+                        document.getElementById(self._addUID('GPlocationOriginPointer_' + id)).checked = false;
+                        if (document.getElementById(self._addUID('GPlocationOriginCoords_' + id)).value == 'Pointer un lieu sur la carte') {
+                            document.getElementById(self._addUID('GPlocationOriginCoords_' + id)).value = '';
+                            document.getElementById(self._addUID('GPlocationOrigin_' + id)).className = 'GPlocationOriginVisible';
+                            document.getElementById(self._addUID('GPlocationOriginCoords_' + id)).className = 'GPlocationOriginHidden';
+                        }
+                    }
+                }
+                if (document.getElementById(self._addUID('GPlocationOriginPointer_' + i)).checked) {
+                    document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).value = '';
+                    for (j = 0; j < points.length; j++) {
+                        tag = points[j].childNodes[0].id;
+                        id = ID.index(tag);
+                        document.getElementById(self._addUID('GPlocationPoint_' + id)).style.cssText = '';
+                    }
+                    if (document.getElementById(self._addUID('GPlocationStageRemove_' + i))) {
+                        document.getElementById(self._addUID('GPlocationStageRemove_' + i)).className = 'GPlocationStageRemove';
+                    }
+                    if (document.getElementById(self._addUID('GPlocationStageAdd'))) {
+                        document.getElementById(self._addUID('GPlocationStageAdd')).className = '';
+                    }
+                    document.getElementById(self._addUID('GPlocationOriginPointer_' + i)).checked = false;
+                    document.getElementById(self._addUID('GPlocationOrigin_' + i)).className = 'GPlocationOriginVisible';
+                    document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).className = 'GPlocationOriginHidden';
+                } else {
+                    document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).value = 'Pointer un lieu sur la carte';
+                    for (j = 0; j < points.length; j++) {
+                        tag = points[j].childNodes[0].id;
+                        id = ID.index(tag);
+                        if (i == id) {
+                            document.getElementById(self._addUID('GPlocationPoint_' + id)).style.cssText = '';
+                        } else {
+                            document.getElementById(self._addUID('GPlocationPoint_' + id)).style.display = 'none';
+                        }
+                    }
+                    if (document.getElementById(self._addUID('GPlocationStageRemove_' + i))) {
+                        document.getElementById(self._addUID('GPlocationStageRemove_' + i)).className = 'GPlocationOriginHidden';
+                    }
+                    if (document.getElementById(self._addUID('GPlocationStageAdd'))) {
+                        document.getElementById(self._addUID('GPlocationStageAdd')).className = 'GPlocationOriginHidden';
+                    }
+                    document.getElementById(self._addUID('GPlocationOriginPointer_' + i)).checked = true;
+                    document.getElementById(self._addUID('GPlocationOrigin_' + i)).className = 'GPlocationOriginHidden';
+                    document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).className = 'GPlocationOriginVisible';
+                    document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).disabled = true;
+                }
+                self.onActivateMapPointClick(e);
+            });
+            return labelOriginPointer;
+        },
+        _createLocationRemovePointElement: function (id) {
+            var self = this;
+            var divRm = document.createElement('div');
+            divRm.id = this._addUID('GPlocationStageRemove_' + id);
+            divRm.className = 'GPlocationStageRemove';
+            divRm.title = 'Supprimer l\'étape';
+            divRm.addEventListener('click', function (e) {
+                var points = document.getElementsByClassName(self._addUID('GPlocationPoint'));
+                var last = points.length - 1;
+                var start = points[0].childNodes[0].id;
+                var end = points[last].childNodes[0].id;
+                var startID = ID.index(start);
+                var endID = ID.index(end);
+                if (id != startID && id != endID) {
+                    var i = ID.index(this.id);
+                    document.getElementById(self._addUID('GPlocationPoint_' + i)).className = 'GPflexInput GPlocationStageFlexInputHidden';
+                    document.getElementById(self._addUID('GPlocationOrigin_' + i)).value = '';
+                    document.getElementById(self._addUID('GPlocationOrigin_' + i)).className = 'GPlocationOriginVisible';
+                    document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).value = '';
+                    document.getElementById(self._addUID('GPlocationOriginCoords_' + i)).className = 'GPlocationOriginHidden';
+                    document.getElementById(self._addUID('GPlocationStageAdd')).style.display = '';
+                    self.onLocationRemovePointClick(e);
+                }
+            });
+            return divRm;
+        },
+        _createLocationAddPointElement: function () {
+            var self = this;
+            var divAdd = document.createElement('div');
+            divAdd.id = this._addUID('GPlocationStageAdd');
+            divAdd.title = 'Ajouter une étape';
+            divAdd.addEventListener('click', function (e) {
+                var lastStage = 1;
+                var nbStages = 0;
+                var points = document.getElementsByClassName(self._addUID('GPlocationPoint'));
+                for (var i = 1; i < points.length - 1; i++) {
+                    var tag = points[i].childNodes[0].id;
+                    var id = ID.index(tag);
+                    if (document.getElementById(self._addUID('GPlocationPoint_' + id))) {
+                        if (document.getElementById(self._addUID('GPlocationPoint_' + id)).className == 'GPflexInput GPlocationStageFlexInputHidden') {
+                            if (lastStage == 1) {
+                                lastStage = id;
+                            }
+                        } else {
+                            nbStages++;
+                        }
+                    }
+                }
+                if (lastStage < points.length) {
+                    document.getElementById(self._addUID('GPlocationPoint_' + lastStage)).className = 'GPflexInput GPlocationStageFlexInput';
+                }
+                if (nbStages == 4) {
+                    document.getElementById(self._addUID('GPlocationStageAdd')).style.display = 'none';
+                }
+                self.onLocationAddPointClick(e);
+            });
+            return divAdd;
+        },
+        _createLocationAutoCompleteResultElement: function (id) {
+            var self = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GPlocationAutoCompleteList_' + id);
+            div.className = 'GPadvancedAutoCompleteList';
+            if (div.addEventListener) {
+                div.addEventListener('click', function (e) {
+                    self.onAutoCompletedResultsItemClick(e);
+                    document.getElementById(self._addUID('GPlocationAutoCompleteList_' + id)).style.display = 'none';
+                }, false);
+            } else if (div.attachEvent) {
+                div.attachEvent('onclick', function (e) {
+                    self.onAutoCompletedResultsItemClick(e);
+                    document.getElementById(self._addUID('GPlocationAutoCompleteList_' + id)).style.display = 'none';
+                });
+            }
+            return div;
+        },
+        _createLocationAutoCompletedLocationElement: function (id, location, n) {
+            var container = document.getElementById(this._addUID('GPlocationAutoCompleteList_' + id));
+            var div = document.createElement('div');
+            div.id = this._addUID('AutoCompletedLocation_' + n);
+            div.className = 'GPautoCompleteProposal';
+            div.innerHTML = location.fullText;
+            container.appendChild(div);
+        },
+        GPdisplayCoordinate: function (value) {
+            var points = document.getElementsByClassName(this._addUID('GPlocationPoint'));
+            for (var i = 0; i < points.length; i++) {
+                var tag = points[i].childNodes[0].id;
+                var id1 = ID.index(tag);
+                if (document.getElementById(this._addUID('GPlocationOriginPointer_' + id1)).checked) {
+                    document.getElementById(this._addUID('GPlocationOriginCoords_' + id1)).value = value;
+                    document.getElementById(this._addUID('GPlocationOriginCoords_' + id1)).disabled = false;
+                    for (var j = 0; j < points.length; j++) {
+                        tag = points[j].childNodes[0].id;
+                        var id2 = ID.index(tag);
+                        document.getElementById(this._addUID('GPlocationPoint_' + id2)).style.cssText = '';
+                        if (document.getElementById(this._addUID('GPlocationStageRemove_' + id2))) {
+                            document.getElementById(this._addUID('GPlocationStageRemove_' + id2)).className = 'GPlocationStageRemove';
+                        }
+                    }
+                    document.getElementById(this._addUID('GPlocationOriginPointer_' + id1)).checked = false;
+                    if (document.getElementById(this._addUID('GPlocationStageAdd'))) {
+                        document.getElementById(this._addUID('GPlocationStageAdd')).className = '';
+                    }
+                    return;
+                }
+            }
+        }
+    };
+    return LocationSelectorDOM;
+}(CommonUtilsSelectorID);
+LeafletControlsUtilsPositionFormater = function () {
+    var PositionFormater = {
+        NORTH: 'N',
+        SOUTH: 'S',
+        EAST: 'E',
+        WEST: 'W',
+        digitSecond: 2,
+        digitDecimal: 5,
+        digitRadian: 8,
+        roundToDecimal: function (inputNum, numPoints) {
+            var multiplier = Math.pow(10, numPoints);
+            return Math.round(inputNum * multiplier) / multiplier;
+        },
+        decimalToRadian: function (location) {
+            var d = 0.017453292519943295;
+            return this.roundToDecimal(location * d, this.digitRadian);
+        },
+        decimalToGrade: function (location) {
+            var d = 1.1111111111111112;
+            return this.roundToDecimal(location * d, this.digitRadian);
+        },
+        decimalToDMS: function (location, hemisphere) {
+            if (location < 0) {
+                location *= -1;
+            }
+            var degrees = Math.floor(location);
+            var minutesFromRemainder = (location - degrees) * 60;
+            var minutes = Math.floor(minutesFromRemainder);
+            var secondsFromRemainder = (minutesFromRemainder - minutes) * 60;
+            var seconds = this.roundToDecimal(secondsFromRemainder, this.digitSecond);
+            var dms = degrees + '\xB0 ' + minutes + '\' ' + seconds + '" ';
+            if (hemisphere) {
+                dms += hemisphere;
+            }
+            return dms;
+        },
+        decimalLatToDMS: function (location) {
+            var hemisphere = location < 0 ? this.SOUTH : this.NORTH;
+            return this.decimalToDMS(location, hemisphere);
+        },
+        decimalLongToDMS: function (location) {
+            var hemisphere = location < 0 ? this.WEST : this.EAST;
+            return this.decimalToDMS(location, hemisphere);
+        },
+        DMSToDecimal: function (degrees, minutes, seconds, hemisphere) {
+            var ddVal = degrees + minutes / 60 + seconds / 3600;
+            ddVal = hemisphere == this.SOUTH || hemisphere == this.WEST ? ddVal * -1 : ddVal;
+            var decimal = this.roundToDecimal(ddVal, this.digitDecimal);
+            return decimal;
+        }
+    };
+    return PositionFormater;
+}();
+LeafletControlsUtilsIconDefault = function (L) {
+    var IconDefault = L.Icon.Default.extend({
+        images: {
+            shadow: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAAApCAYAAACoYAD2AAAC5ElEQVRYw+2YW4/TMBCF45S0S1luXZCABy5CgLQgwf//S4BYBLTdJLax0fFqmB07nnQfEGqkIydpVH85M+NLjPe++dcPc4Q8Qh4hj5D/AaQJx6H/4TMwB0PeBNwU7EGQAmAtsNfAzoZkgIa0ZgLMa4Aj6CxIAsjhjOCoL5z7Glg1JAOkaicgvQBXuncwJAWjksLtBTWZe04CnYRktUGdilALppZBOgHGZcBzL6OClABvMSVIzyBjazOgrvACf1ydC5mguqAVg6RhdkSWQFj2uxfaq/BrIZOLEWgZdALIDvcMcZLD8ZbLC9de4yR1sYMi4G20S4Q/PWeJYxTOZn5zJXANZHIxAd4JWhPIloTJZhzMQduM89WQ3MUVAE/RnhAXpTycqys3NZALOBbB7kFrgLesQl2h45Fcj8L1tTSohUwuxhy8H/Qg6K7gIs+3kkaigQCOcyEXCHN07wyQazhrmIulvKMQAwMcmLNqyCVyMAI+BuxSMeTk3OPikLY2J1uE+VHQk6ANrhds+tNARqBeaGc72cK550FP4WhXmFmcMGhTwAR1ifOe3EvPqIegFmF+C8gVy0OfAaWQPMR7gF1OQKqGoBjq90HPMP01BUjPOqGFksC4emE48tWQAH0YmvOgF3DST6xieJgHAWxPAHMuNhrImIdvoNOKNWIOcE+UXE0pYAnkX6uhWsgVXDxHdTfCmrEEmMB2zMFimLVOtiiajxiGWrbU52EeCdyOwPEQD8LqyPH9Ti2kgYMf4OhSKB7qYILbBv3CuVTJ11Y80oaseiMWOONc/Y7kJYe0xL2f0BaiFTxknHO5HaMGMublKwxFGzYdWsBF174H/QDknhTHmHHN39iWFnkZx8lPyM8WHfYELmlLKtgWNmFNzQcC1b47gJ4hL19i7o65dhH0Negbca8vONZoP7doIeOC9zXm8RjuL0Gf4d4OYaU5ljo3GYiqzrWQHfJxA6ALhDpVKv9qYeZA8eM3EhfPSCmpuD0AAAAASUVORK5CYII=',
+            color: {
+                blue: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAGmklEQVRYw7VXeUyTZxjvNnfELFuyIzOabermMZEeQC/OclkO49CpOHXOLJl/CAURuYbQi3KLgEhbrhZ1aDwmaoGqKII6odATmH/scDFbdC7LvFqOCc+e95s2VG50X/LLm/f4/Z7neY/ne18aANCmAr5E/xZf1uDOkTcGcWR6hl9247tT5U7Y6SNvWsKT63P58qbfeLJG8M5qcgTknrvvrdDbsT7Ml+tv82X6vVxJE33aRmgSyYtcWVMqX97Yv2JvW39UhRE2HuyBL+t+gK1116ly06EeWFNlAmHxlQE0OMiV6mQCScusKRlhS3QLeVJdl1+23h5dY4FNB3thrbYboqptEFlphTC1hSpJnbRvxP4NWgsE5Jyz86QNNi/5qSUTGuFk1gu54tN9wuK2wc3o+Wc13RCmsoBwEqzGcZsxsvCSy/9wJKf7UWf1mEY8JWfewc67UUoDbDjQC+FqK4QqLVMGGR9d2wurKzqBk3nqIT/9zLxRRjgZ9bqQgub+DdoeCC03Q8j+0QhFhBHR/eP3U/zCln7Uu+hihJ1+bBNffLIvmkyP0gpBZWYXhKussK6mBz5HT6M1Nqpcp+mBCPXosYQfrekGvrjewd59/GvKCE7TbK/04/ZV5QZYVWmDwH1mF3xa2Q3ra3DBC5vBT1oP7PTj4C0+CcL8c7C2CtejqhuCnuIQHaKHzvcRfZpnylFfXsYJx3pNLwhKzRAwAhEqG0SpusBHfAKkxw3w4627MPhoCH798z7s0ZnBJ/MEJbZSbXPhER2ih7p2ok/zSj2cEJDd4CAe+5WYnBCgR2uruyEw6zRoW6/DWJ/OeAP8pd/BGtzOZKpG8oke0SX6GMmRk6GFlyAc59K32OTEinILRJRchah8HQwND8N435Z9Z0FY1EqtxUg+0SO6RJ/mmXz4VuS+DpxXC3gXmZwIL7dBSH4zKE50wESf8qwVgrP1EIlTO5JP9Igu0aexdh28F1lmAEGJGfh7jE6ElyM5Rw/FDcYJjWhbeiBYoYNIpc2FT/SILivp0F1ipDWk4BIEo2VuodEJUifhbiltnNBIXPUFCMpthtAyqws/BPlEF/VbaIxErdxPphsU7rcCp8DohC+GvBIPJS/tW2jtvTmmAeuNO8BNOYQeG8G/2OzCJ3q+soYB5i6NhMaKr17FSal7GIHheuV3uSCY8qYVuEm1cOzqdWr7ku/R0BDoTT+DT+ohCM6/CCvKLKO4RI+dXPeAuaMqksaKrZ7L3FE5FIFbkIceeOZ2OcHO6wIhTkNo0ffgjRGxEqogXHYUPHfWAC/lADpwGcLRY3aeK4/oRGCKYcZXPVoeX/kelVYY8dUGf8V5EBRbgJXT5QIPhP9ePJi428JKOiEYhYXFBqou2Guh+p/mEB1/RfMw6rY7cxcjTrneI1FrDyuzUSRm9miwEJx8E/gUmqlyvHGkneiwErR21F3tNOK5Tf0yXaT+O7DgCvALTUBXdM4YhC/IawPU+2PduqMvuaR6eoxSwUk75ggqsYJ7VicsnwGIkZBSXKOUww73WGXyqP+J2/b9c+gi1YAg/xpwck3gJuucNrh5JvDPvQr0WFXf0piyt8f8/WI0hV4pRxxkQZdJDfDJNOAmM0Ag8jyT6hz0WGXWuP94Yh2jcfjmXAGvHCMslRimDHYuHuDsy2QtHuIavznhbYURq5R57KpzBBRZKPJi8eQg48h4j8SDdowifdIrEVdU+gbO6QNvRRt4ZBthUaZhUnjlYObNagV3keoeru3rU7rcuceqU1mJBxy+BWZYlNEBH+0eH4vRiB+OYybU2hnblYlTvkHinM4m54YnxSyaZYSF6R3jwgP7udKLGIX6r/lbNa9N6y5MFynjWDtrHd75ZvTYAPO/6RgF0k76mQla3FGq7dO+cH8sKn0Vo7nDllwAhqwLPkxrHwWmHJOo+AKJ4rab5OgrM7rVu8eWb2Pu0Dh4eDgXoOfvp7Y7QeqknRmvcTBEyq9m/HQQSCSz6LHq3z0yzsNySRfMS253wl2KyRDbcZPcfJKjZmSEOjcxyi+Y8dUOtsIEH6R2wNykdqrkYJ0RV92H0W58pkfQk7cKevsLK10Py8SdMGfXNXATY+pPbyJR/ET6n9nIfztNtZYRV9XniQu9IA2vOVgy4ir7GCLVmmd+zjkH0eAF9Po6K61pmCXHxU5rHMYd1ftc3owjwRSVRzLjKvqZEty6cRUD7jGqiOdu5HG6MdHjNcNYGqfDm5YRzLBBCCDl/2bk8a8gdbqcfwECu62Fg/HrggAAAABJRU5ErkJggg==',
+                orange: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAASAAAAEgARslrPgAABghJREFUWMOdl1uInGcdxn/feWa+mflmJmZbqVqKigewKK5goHgRSEm8EC88F6tBFLfgZbzJnVdRYWExrVBoXazWlAYL0dVisLBYzEUUSbeNjZQmxGZ3NjO7c57v/P69mNnD7MzuzvrCA8PM+/+e93n+h/cb7c9PzXKE9RHAG36+BXRPP3390CDtT3MHklSA7wKngVOWbaOhA5AkEUqpKnAFePHMM9eX9yeZrMQAzgHni14ln826ZLLu2KY0TfD7XXq9NoHffxX48Zmnr6+MkSyNK6kAl4ql8qlisYxpWagoJA16gIxs1E0bI1cAoNNuslFb94Env/jM9csj+0SEXaiIyN+9cuVU5dhxdEmI23XSoAOoIckOVBISt+vE7Q0KRY8H3v+BbM7Nv7w0Nzs3QrLHopdL5crHyqUKSbdB6ndA1BRIiVs1Mo5NySsD/GJpbvbkjpKds50rFL2T5VKZpNdAkmjiAzXDHOye8FvS2cC2LWZmHjAELv1xbrYyIFGCKKmIkvMlr4iK+0gaDe0ZQHcyWIUyVqGMmDZWvoRVKGO63sg+UMSdGq6bo+R5x0XJuYFdGqDxLa9UzJumQRp0R3y3ChU002Zjc5Pbd+6wGem8e/sO6+vrBGGIVagMTdmJScMepZIHGj/4ww8/a5jDevl63s2h4nAgfbhM1yOMQt67V+WjZ87y+VNPYmXzANz7x19YufQzilFIySsTt+vbcSrsYTlZnEymEgTBCV2U5EXJiUzGJg1aI9I1w6DZbPHoE+f5+Jee2iYAeGj2cR479zyNjo+SFN12xqzLZRxEyWld4EOWbRmIApVuJ1E3LaIwRLkzPPzYl8caUURwZz7Iw1/4Cq1WG8POjBSBCvvYtonAJ3URqeiaNlYpuuXg+wHlRz41kQBAKUX5w5+m1/PHKk7SBF0DEfFMgUjJMGnaro7WFGig0nhfAhEhjQI0TRuL1wwNFSkEfF2Ee3GSjp0kDXq4WZv7b19HJeNEWySrN/5G3nUQlezpJ4MkTRHhni4i1ThOuipNByfakhsHmIZGRnV565WLYyoA1t68RuONq3j5DKnfHiXRdKIoRkTuGl/9zIMCfC7rGJ/I5vOocGsQCoiQz7vc/8+/WH37BrnKgzjFY7RWb/Pu8mVWLv2UmUoOxzYGJFtxmobhZFmrd0hS9SPtpbOPApx0s/ZfH3moRNyujU5aO4eRcWl2AjZbPn6YYFsGXt6h4mUxDX0sxioep9kJeG+9ffVrz994fKsZX+v60bVuPzzhFo6RdHY1VtRDEp9S4RilgjPyMBX2iXu90dIbFsFm20fgJwCm7BTEzzda/u/zrjVspl2JVoq4vc40yyrO0OqGdPvxa9/41Y3XYfQ+udLshO8EQYyZK0454idAKTYafUTkwrblu0Z9KjBfb/pouvl/EZhuma4f0e7H//zm4htXt0n23HaL9VZQS5IU3c4emUTTNOoNH9hRsVcJAr7As7VWgJHJDTp4SpiFMv0oodGLbwm8MkoyescjIgtrm4GvlEI37SOo0Kk1AkTkwhOLK+keEtiDmggv1FshRrYwFYGRLRJEKfV2fFeEF/dW3F67tjB/txamIoKm65N37IJu2dRaEQLz3/71m9E4ybhdiMgtEVna7EQY+Qoial/oTo4oTqk2opqIPDepd/QDzjh/vxmDOtgq3cqy3ogQuPidF97qTiaZrAQRWW776bVOkGIW3jfZJidHqoTVRtwVkYX9psCkxO/GwnojRhvMlvGE2zmqzRgRfnn2Nzdb+5McnNbL9a56x48FI+vtSbaDaPDfjSQSmD9onh1kFyKSishCtZmgW/ZY2a5txojI4vd+e7N6CMmBdiHC4lojrcWpoDsuIGimhYhwp5amIlzgkKUf1gMgXZBnq40Ew8kNBmGuxHozAeSl7//u37cPJTmUYoCLdzdVJMNcgLDWFoTDVUxrFyJURVisNhVGzqPWVvQCWRJhZSqS4Qv3NFhYaw10rbUENC4MansaJYO/DtPgZi+QK7W20OrLsih5XZRMSTJdTrZHzWpzkIut76az62hrueXzHPDqUYL+B8XVKUzuUimfAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDEyLTA4LTE4VDE0OjUwOjU2KzAxOjAwFlCkXwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxMi0wOC0xOFQxNDo1MDo1NiswMTowMGcNHOMAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAAAElFTkSuQmCC',
+                red: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAASAAAAEgARslrPgAABe5JREFUWMOdlWuIXGcZx3/nPbe5ZWbO2c0a8VIEpSq0io2QBT8FUlIFEbzfokUUKfgxIuSbn+JtYTEQqFQCQmkxVIiNFhcLwZoVtrFNt40ESrPEJju7s/eZM+f+Pn6Y2XVnZ3Zn0/fwcA7veZ/ze5//87zPMf56fJIHGB8Far3n20D79Nz1kU7GXw6G+MD3gdPAKdtxMJQFQJZEaK0bwBXg2Sfmrl87AHJi2LwJnAXOVf3xSrFcoVAuDyzKs4yw3SLY2iTqBC8BP31ibnZ+AHJ1MBIfeK7qeaeqno9l2+g4IQ86ILpvoXIczCMVAFob66wuLYXAmc/PXb/cB3nxsRN7AdfrY2MPe+Pj6Cjufnyk6Aa2XyfshLQ21glarae+8OrsxZ3N7JHoj3Xff9jzx8jWN8hbbdB6tOU5aXOVguNQ98YAfnv1+OTJHYgAPTt7pFY76Xk+2fo6kiSg8wEzLLMr25B32eoqjm0x8b5jpsBzLx6f9LsQARF8Ec7Vq1V0J0CSuM9ZFVxsr47t1RHHxq7XsL06Vq06AEqby5RLReq12lERzvbkEkC+VatWKpapyNtt6JERwfY9DMdmdW2NOwsLrCmDdxYWWFpaIopjbN/rarLLJw8C6rUqID/682MnTEsQgK9XSiV0nHQ17g2rViWOI95tLPOxJ89w4sx3sCvdarr3txnmf/kbqnFE3auTrqzu+OkgwC4WcAuuH0XRpBKhIsJkwbHJN9f79TcVG5tbPHruZ3z8qR/vAAA+8PgpPvf737Eehug8Rbn2gHQl10WE00rgw7ZtmdtVspMH2yKJY/TEBA996YsDVSsilD/0QR76ypfZ3GphFgp9AN3p4FgmAp9UIuIrQw2UpXJdwijGe+SRoQAArTXepz9FEEbdfOzylyxHddfWLEESLbpblrtPtM4AQafJvgARIY8iDMMY8DcM6a5BQiUY99I8H9hJHgSUHZvluVfRaToA2obc/8c/qbg2kqV9/oapyPIcwbinRKSRZnlb53l3R9vhRjGWAYV2i7cuXByIAmBx9l+sz8xQK7jkW1v9EKVI0hQRuWt+9dj7Bfhs0VSfKFZK6CDoq/lKucTya69x/+Y8pWPHcMd8Nu8s8M7lF5j/xa+ZKBVwTdWFbPsZBmaxwGIrINP6J8bzj34G4GTZcf7+kXqFtNns77SlMma5xEaUsBbGhFmGY5rUXBu/6GIpNeBjHz3KRpTw7lZ75ms3bzxudQXg5XaSzLbjZLI8Nka2srLrYLWRqEPdH6Pu2n0f050OaRD0l54yQIS1MELg5wDbEIBfrYbRCxW3MvDfkEyTLi+NavjdKMYn2Ixi2mn28jdu3nil1yCFnl3ZiNO3ozjtNb5DtPihbV+z2okRkfPDWn0uMLUSxhim9Z4AlufRThK20uzGN9/498wOhN0HUfSllShuZnmOKhXZ826kGYbBSicG0ed3S7g7EgRCgaebYYxZLvW/GWGW79HJM9bT7LbAn/oh/8/Jtk0vRkmotUY5zqGlMpSi2cvFt+dfz/dEYrDHmoLxh5Uwxjxy5FAAs1olynJWUn1XMJ7dW3FKGHpN3Y2yXEQwTDVSKuU6NKMEQaa+++brySBkUC5E5LaIXF2LE0zfR7Te11SpRJLlNJK8KSLPDDs76oA9Ti3H+UipVLHIUpggcOF7b73RHg4ZHgkicm0r17OtLMc6Oj5cpnKJXAv3U90Wken9uoAaUZzTS1GGIQxPeLFEI04RuPjkrfnN9wq5vKJ5OxTBrNb2JNtFFPw3lURg6qB+dpBciEguItONOEO5zkDZLoYpInLpB7fmGwdDRp/nS4sZzVQEVS6DCIZjIyIspOQC5xkx1O6/4D7WRuTpRpRhlkrdRlirsxRnIPL8D//z5p2RkH0O497rwt2cRBBUwQWExVwQZGQUPchAWxlmDcG41Eg0Zq1GM9EEoq4KxvyhIA/QaacXs+5z736+O3+YSEamZMduBaKuNFNhU9Q1EV6RwzEOnZOdxnk/7eZie+aQcj3QuLaJegZ46UGc/gcUeTtzDg/o4wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wOC0xOFQxNDo1MDo1NiswMTowMBZQpF8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDgtMThUMTQ6NTA6NTYrMDE6MDBnDRzjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAABJRU5ErkJggg==',
+                green: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wJCgoDDgqHD/MAAAZVSURBVFjDpZZtiFxXGcd/c+69M7PzurvdTTZNGvxQTCJqFSok+MmFQPSDUlsQhBaxWNhorQlWPxSKTYqsFLYGA8VCISDESIpCILYQW4xJNtHGGBooZtl16UrKNrMvM7N3Xu6555zHD7OZ7OzsW/Be/nBnznnO/zzP83/OcxKPv/IOW32KXzj2KFBc/nm7cuvl8IOXD21ql3j8lT9vsOjxfuB7wCHgoAoUCV8BYJsWRGaBc8DpvzwxfnF9kl90kxQ+f9wDXgReyg9kc8VkH4Wg2DUvdpqyXqRcKxOH5l3gZ+89OX5rDZLzqwhe7QfOZAcyB4fSO0h6KbSNqNt6F0lSJcn4WQA+bcyycHehATzz3pPjb6+cp0SEe8jvOdYvsRvPDmQOPpLZjRXLYjRPzYSIuC5EtsliNE9ZL7ItvY2dD+/sSRaDs8Nn9o90kLQ92HvcA87mduT27Mw8QiWuUDMhVuymMC5mPpoj42UYyu0A+M3wmf3D90lEQATgxfT29PDDPTup6jKx08gar6+CNf8XhEW9QEqlGNw16AFnhs/s72+FC6Gw79V+4KXtPUPUbZ3IRR07DVSSQlCkEBRRCdX+zvn5Lq/mohKFoEh2KDO4LB4ULUe+mxpI5RSKMA5xIm0Ug16SKsknjTtMfTxFGIdMfTzFzOIMoVmiGPQCdNjUTY3B9HZEeO5rv9/v+YggwncK6QKxxB3qyQU5aibk7iclvv3YUzz91WfJ+wUALsy+w+sf/opGusFgahuLerFt17BN0l4PQc7v10vmgJ/f98sccCDjZ5mP5jpIvITHYljm+QNH+NaupzrGDg59nc/m9/KDC08TD8UEyqdhG+1xh8PP+eglc0jhZLeXUp4V2yFPPxFQNzWymWwXAYAg7M5+hm/s+yZzzRIpL91hXzc1kioAJ59TQH9C3WOXNlJeitCEfLH3S2sSAFgxPNb7ZXQl7rJ3IiRaCxd9caLFgXUGcdJeyDiDiKBdtC6BE6FhGygv0WUvnsOKRZw0FHDHRg6HdCzWtHXyQZ4bn17HrBKEFdNaAMel0l/xcz5WbOd5hcI4A3BHiWPWaReKuNYOjEOMw2hDggQudpyceL3DC9cqXsZLl7g+9Q8KQYEls9S2FePwEgrbsIhjxuvb+2tJDYx/RXJuXzbI0dRR+xBwypDtyXLrvx9yLbzC9vR2HkoO8J9wkrMzp/nt+Bv0DKbwVUCj0VxxeEAQJKneDRErz/siAk5ONueiJzI7MrAirroe4zJC70NFphem+PnkUWzkUH6CZG9A364iXsKjulTprK98nqV6Fde0F/72/Q8+8hGh8u+fvl/Y89rVWn/tQDaXI6wu3e8ZYYzxLflsjlymU2UN2yAO4zUbVXNeIyLHAHzuJ/w1XY7/mN7mWKUBJHZUy9UttehsMUtYD7EN8/6lZ69fBmiFCxDLuWhBT0b90aN+zm9r/0EfEdfywjLaddRXJ45aYCxa0PjKp53FB0CqN0mzGWFC88/Lz12/sKIzrpjn5FRzLioZZ/B6fMTxQFAkiBY04mS0szOuYKlOHG0g8mazFOGlFGJly0jmfXQ9Rpf1bUT+tG6PX87PiWg+aiDgpbyWpLeARKCIyjHA6JWRG3ZVjxdWojJxpAT8rjkX4We9LSU7KATYhiWu6Bng9OpxtVYCxTHWLEX2XmE6tzGUnyAqx4hj7MrIDd1FsjpcIkJl4oXbYuW8rhqSfUkkduvCSymsdkRzUUmsvLWWp2o9OYqTsWhRb6pcP+ujyzHi5OTVH/8rXJNkLU9EhOrUCxdNzVw1NUN6ILlmsv2MhxhHcy4KgRPr5awr8Z3ghC7r5Uru3oif8YgWNMAb135ys7I+yYbx4O24aiZt5Ej2JjsvGSkPBKJ5rRHGNlLfuuESESqTP7IiLW+UrxBLG0E+aFW3cOrakZuzG5JsHC4BOKUrpuRM64ojTlB+AhGhOa8tMLpZHanN1FOZ/GEIvBlXYvweBSIk+wJ0q7r/8PejN6c3JdnSCevkZLSgtdhWLsSBLmtYdRD+H+ESKlOHZ8XJqbgaExQC4iWD0+58Zerwra2RbM7B8qX8hK7EiBN0WSPC6OoOun5O2NpbnT78kdXunKlbbOQuVqcPX5YtsqgH636M6bIGYbTj/rN5Trb+VKdHLtqme6s6PfLug9j9D/FCc1g2qf7VAAAAAElFTkSuQmCC'
+            }
+        },
+        initialize: function (color, options) {
+            L.Util.extend(this.options, options);
+            switch (color) {
+            case 'red':
+                this.options.iconUrl = this.images.color.red;
+                break;
+            case 'green':
+                this.options.iconUrl = this.images.color.green;
+                break;
+            case 'orange':
+                this.options.iconUrl = this.images.color.orange;
+                break;
+            case 'blue':
+                this.options.iconUrl = this.images.color.blue;
+                break;
+            default:
+                this.options.iconUrl = this.images.color.blue;
+            }
+            this.options.shadowUrl = this.images.shadow;
+        }
+    });
+    return IconDefault;
+}(leaflet);
+LeafletControlsLocationSelector = function (L, woodman, Gp, RightManagement, ID, LocationSelectorDOM, PositionFormater, IconDefault) {
+    var LocationSelector = L.Control.extend({
+        includes: LocationSelectorDOM,
+        options: {
+            position: 'topleft',
+            tag: {
+                id: 0,
+                unique: null,
+                label: '>',
+                color: 'blue',
+                display: true,
+                addOption: false,
+                removeOption: false
+            },
+            disableReverse: false,
+            displayInfo: true,
+            autocompleteOptions: {},
+            reverseGeocodeOptions: {}
+        },
+        initialize: function (options) {
+            L.Util.setOptions(this, options);
+            this._uid = this.options.tag.unique || null;
+            this._activeDragAndDrop = false;
+            this._pressedKeyOnDragAndDrop = false;
+            this._map = null;
+            this._inputsContainer = null;
+            this._inputLabelContainer = null;
+            this._inputAutoCompleteContainer = null;
+            this._inputShowPointerContainer = null;
+            this._inputCoordinateContainer = null;
+            this._coordinate = null;
+            this._suggestedContainer = null;
+            this._suggestedLocations = [];
+            this._currentLocation = null;
+            this._marker = null;
+            this._resources = {};
+            this._noRightManagement = false;
+            this._checkRightsManagement();
+            this._container = this._uid ? this._initLayout() : null;
+        },
+        onAdd: function () {
+            this._uid = ID.generate();
+            var container = this._initLayout();
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            return container;
+        },
+        onRemove: function () {
+        },
+        getCoordinate: function () {
+            return this._coordinate;
+        },
+        getCoordinateInverse: function () {
+            if (!this._coordinate) {
+                return;
+            }
+            var coordinateInv = {
+                x: this._coordinate.y,
+                y: this._coordinate.x
+            };
+            return coordinateInv;
+        },
+        setMap: function (map) {
+            if (!this._map) {
+                this._map = map;
+            }
+        },
+        clear: function () {
+            this._setCursor();
+            this._setMarker();
+            this._clearResults();
+            this._inputLabelContainer.click();
+        },
+        dragging: function (active) {
+            if (this._marker) {
+                if (active) {
+                    this._marker.dragging.enable();
+                } else {
+                    this._marker.dragging.disable();
+                }
+            }
+        },
+        _initLayout: function () {
+            var id = this.options.tag.id;
+            var container = this._createMainContainerElement();
+            var inputs = this._inputsContainer = this._createLocationPointElement(id, this.options.tag.display);
+            container.appendChild(inputs);
+            var _inputLabel = this._inputLabelContainer = this._createLocationPointLabelElement(id, this.options.tag.label);
+            inputs.appendChild(_inputLabel);
+            var _inputAutoComplete = this._inputAutoCompleteContainer = this._createLocationAutoCompleteteInputElement(id);
+            inputs.appendChild(_inputAutoComplete);
+            var _inputCoordinate = this._inputCoordinateContainer = this._createLocationCoordinateInputElement(id);
+            inputs.appendChild(_inputCoordinate);
+            var _inputShowPointer = this._inputShowPointerContainer = this._createLocationPointerShowInputElement(id);
+            inputs.appendChild(_inputShowPointer);
+            var _inputPointer = this._createLocationPointerInputElement(id);
+            inputs.appendChild(_inputPointer);
+            if (this.options.tag.addOption) {
+                var _inputAddStage = this._createLocationAddPointElement();
+                inputs.appendChild(_inputAddStage);
+            }
+            if (this.options.tag.removeOption) {
+                var _inputRemoveStage = this._createLocationRemovePointElement(id);
+                inputs.appendChild(_inputRemoveStage);
+            }
+            var results = this._suggestedContainer = this._createLocationAutoCompleteResultElement(id);
+            container.appendChild(results);
+            return container;
+        },
+        _checkRightsManagement: function () {
+            var _opts = null;
+            var _res = [];
+            var _key = null;
+            _key = this.options.reverseGeocodeOptions.apiKey;
+            _opts = this.options.reverseGeocodeOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = [
+                    'PositionOfInterest',
+                    'StreetAddress'
+                ];
+            }
+            var rightManagementRerverse = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['ReverseGeocode']
+            });
+            _key = this.options.autocompleteOptions.apiKey;
+            _opts = this.options.autocompleteOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = [
+                    'PositionOfInterest',
+                    'StreetAddress'
+                ];
+            }
+            var rightManagementAutoComplete = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['AutoCompletion']
+            });
+            if (!rightManagementRerverse && !rightManagementAutoComplete) {
+                this._noRightManagement = true;
+            }
+            if (rightManagementAutoComplete) {
+                this._resources['AutoCompletion'] = {};
+                this._resources['AutoCompletion']['resources'] = rightManagementAutoComplete['AutoCompletion'];
+                this._resources['AutoCompletion']['key'] = rightManagementAutoComplete['key'];
+            }
+            if (rightManagementRerverse) {
+                this._resources['ReverseGeocode'] = {};
+                this._resources['ReverseGeocode']['resources'] = rightManagementRerverse['ReverseGeocode'];
+                this._resources['ReverseGeocode']['key'] = rightManagementRerverse['key'];
+            }
+        },
+        _setLabel: function (label) {
+            this._inputAutoCompleteContainer.value = label || '';
+        },
+        _setCoordinate: function (oLatLng) {
+            this._coordinate = {
+                x: oLatLng.lng,
+                y: oLatLng.lat
+            };
+            var lat = null;
+            var lng = null;
+            if (false) {
+                lat = PositionFormater.decimalLatToDMS(oLatLng.lat);
+                lng = PositionFormater.decimalLongToDMS(oLatLng.lng);
+            } else {
+                lat = PositionFormater.roundToDecimal(oLatLng.lat, 4);
+                lng = PositionFormater.roundToDecimal(oLatLng.lng, 4);
+            }
+            var value = lng + ' , ' + lat;
+            this.GPdisplayCoordinate(value);
+        },
+        _setPosition: function (position) {
+            var map = this._map;
+            map.panTo(L.latLng(position.y, position.x));
+        },
+        _setMarker: function (position, information, display) {
+            if (this._activeDragAndDrop) {
+                return;
+            }
+            var map = this._map;
+            if (this._marker != null) {
+                this._marker.off('mousedown', this.onMouseDownMarker, this);
+                this._marker.off('dragstart', this.onStartDragMarker, this);
+                this._marker.off('drag', this.onDragMarker, this);
+                this._marker.off('dragend', this.onEndDragMarker, this);
+                map.removeLayer(this._marker);
+                this._marker = null;
+            }
+            if (position) {
+                var options = {
+                    icon: new IconDefault(this.options.tag.color),
+                    draggable: true,
+                    clickable: true,
+                    zIndexOffset: 1000
+                };
+                this._marker = L.marker(L.latLng(position.y, position.x), options);
+                this._marker.on('mousedown', this.onMouseDownMarker, this);
+                this._marker.on('dragstart', this.onStartDragMarker, this);
+                this._marker.on('drag', this.onDragMarker, this);
+                this._marker.on('dragend', this.onEndDragMarker, this);
+                this._marker.addTo(map);
+                if (display) {
+                    var popupContent = null;
+                    if (typeof information !== 'string') {
+                        if (information.fields.fullText) {
+                            popupContent = information.fields.fullText;
+                        } else {
+                            var values = [];
+                            values.push(information.fields.street || '');
+                            values.push(information.fields.postalCode || '');
+                            values.push(information.fields.commune || '');
+                            if (information.type === 'PositionOfInterest') {
+                                values.push(information.fields.poi || '');
+                                values.push(information.fields.kind || '');
+                            }
+                            popupContent = values.join(' - ');
+                        }
+                    } else {
+                        popupContent = information;
+                    }
+                    this._marker.bindPopup(popupContent);
+                }
+            }
+        },
+        _setCursor: function (cursor) {
+            var div = this._map.getContainer();
+            if (cursor) {
+                div.style.cursor = cursor;
+            } else {
+                div.style.cursor = null;
+            }
+        },
+        _clearResults: function () {
+            this._currentLocation = null;
+            this._coordinate = null;
+            this._clearSuggestedLocation();
+        },
+        _clearSuggestedLocation: function () {
+            this._suggestedLocations = [];
+            if (this._suggestedContainer) {
+                while (this._suggestedContainer.firstChild) {
+                    this._suggestedContainer.removeChild(this._suggestedContainer.firstChild);
+                }
+            }
+        },
+        _requestAutoComplete: function (settings) {
+            if (!settings || Object.keys(settings).length === 0) {
+                return;
+            }
+            if (!settings.text) {
+                return;
+            }
+            if (this._noRightManagement) {
+                console.log('no rights for all service !?');
+                return;
+            }
+            if (!this._resources['AutoCompletion']) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            var resources = this._resources['AutoCompletion'].resources;
+            if (!resources || Object.keys(resources).length === 0) {
+                return;
+            }
+            var key = this._resources['AutoCompletion']['key'];
+            var options = {};
+            L.Util.extend(options, this.options.autocompleteOptions);
+            L.Util.extend(options, settings);
+            L.Util.extend(options, { apiKey: options.apiKey || this.options.apiKey || key });
+            Gp.Services.autoComplete(options);
+        },
+        _fillAutoCompletedLocationListContainer: function (locations) {
+            if (!locations || locations.length === 0) {
+                return;
+            }
+            var element = this._suggestedContainer;
+            if (element.childElementCount) {
+                while (element.firstChild) {
+                    element.removeChild(element.firstChild);
+                }
+            }
+            for (var i = 0; i < locations.length; i++) {
+                this._createLocationAutoCompletedLocationElement(this.options.tag.id, locations[i], i);
+            }
+            this._suggestedLocations = locations;
+        },
+        _requestReverseGeocode: function (settings) {
+            if (!settings || Object.keys(settings).length === 0) {
+                return;
+            }
+            if (!settings.position || Object.keys(settings.position).length === 0) {
+                return;
+            }
+            if (this._noRightManagement) {
+                console.log('no rights for all service !?');
+                return;
+            }
+            if (!this._resources['ReverseGeocode']) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            var resources = this._resources['ReverseGeocode'].resources;
+            if (!resources || Object.keys(resources).length === 0) {
+                return;
+            }
+            var key = this._resources['ReverseGeocode']['key'];
+            var options = {};
+            L.Util.extend(options, this.options.reverseGeocodeOptions);
+            L.Util.extend(options, settings);
+            L.Util.extend(options, {
+                returnFreeForm: true,
+                filterOptions: { type: ['StreetAddress'] }
+            });
+            L.Util.extend(options, { apiKey: options.apiKey || this.options.apiKey || key });
+            Gp.Services.reverseGeocode(options);
+        },
+        _displayResultOfCoordinate: function (oLatLng) {
+            this._setCoordinate(oLatLng);
+            this._setMarker({
+                x: oLatLng.lng,
+                y: oLatLng.lat
+            }, null, false);
+            this.onActivateMapPointClick();
+        },
+        _displayResultOfLabel: function (oLocation) {
+            var places = oLocation.placeAttributes;
+            var label = places.number + ' ' + places.street + ', ' + places.postalCode + ' ' + places.commune;
+            this._setCoordinate({
+                lat: oLocation.position.x,
+                lng: oLocation.position.y
+            });
+            this._setLabel(label);
+            this._setMarker({
+                x: oLocation.position.y,
+                y: oLocation.position.x
+            }, null, false);
+            this._inputShowPointerContainer.checked = false;
+            this._inputAutoCompleteContainer.className = 'GPlocationOriginVisible';
+            this._inputCoordinateContainer.className = 'GPlocationOriginHidden';
+            this.onActivateMapPointClick();
+        },
+        onAutoCompleteSearchText: function (e) {
+            var value = e.target.value;
+            if (!value) {
+                return;
+            }
+            if (this._noRightManagement) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            this._currentLocation = value;
+            if (value.length < 3) {
+                return;
+            }
+            var context = this;
+            this._requestAutoComplete({
+                text: value,
+                maximumResponses: 5,
+                onSuccess: function (results) {
+                    if (results) {
+                        var locations = results.suggestedLocations;
+                        context._fillAutoCompletedLocationListContainer(locations);
+                    }
+                },
+                onFailure: function (error) {
+                    context._clearSuggestedLocation();
+                }
+            });
+        },
+        onAutoCompletedResultsItemClick: function (e) {
+            var idx = ID.index(e.target.id);
+            if (!idx) {
+                return;
+            }
+            var position = {
+                x: this._suggestedLocations[idx].position.x,
+                y: this._suggestedLocations[idx].position.y
+            };
+            var info = {
+                type: this._suggestedLocations[idx].type,
+                fields: this._suggestedLocations[idx]
+            };
+            var label = this._suggestedLocations[idx].fullText;
+            this._setLabel(label);
+            this._setPosition(position);
+            this._setMarker(position, info, this.options.displayInfo);
+            this._coordinate = position;
+        },
+        onActivateMapPointClick: function (e) {
+            var map = this._map;
+            if (this._inputShowPointerContainer.checked) {
+                if (!this._activeDragAndDrop) {
+                    map.on('click', this.onMouseMapClick, this);
+                    this._setCursor('crosshair');
+                    this._setMarker();
+                    this._clearResults();
+                }
+            } else {
+                if (!this._activeDragAndDrop) {
+                    map.off('click', this.onMouseMapClick, this);
+                    this._setCursor();
+                }
+            }
+        },
+        onLocationClearPointClick: function (e) {
+            this._setCursor();
+            this._setMarker();
+            this._clearResults();
+            this._inputAutoCompleteContainer.focus();
+        },
+        onLocationRemovePointClick: function (e) {
+            this._setCursor();
+            this._setMarker();
+            this._clearResults();
+        },
+        onLocationAddPointClick: function (e) {
+        },
+        onMouseMapClick: function (e) {
+            var oLatLng = e.latlng;
+            if (this.options.disableReverse || this._noRightManagement) {
+                this._displayResultOfCoordinate(oLatLng);
+            } else {
+                var self = this;
+                this._requestReverseGeocode({
+                    position: {
+                        x: oLatLng.lat,
+                        y: oLatLng.lng
+                    },
+                    srs: 'EPSG:4326',
+                    onSuccess: function (results) {
+                        if (results.locations.length !== 0) {
+                            var oLocation = results.locations[0];
+                            self._displayResultOfLabel(oLocation);
+                        } else {
+                            self._displayResultOfCoordinate(oLatLng);
+                        }
+                    },
+                    onFailure: function (error) {
+                        self._displayResultOfCoordinate(oLatLng);
+                    }
+                });
+            }
+        },
+        onStartDragMarker: function () {
+            if (!this._marker) {
+                return;
+            }
+            this._activeDragAndDrop = true;
+            this._inputShowPointerContainer.checked = true;
+            this._inputAutoCompleteContainer.className = 'GPlocationOriginHidden';
+            this._inputCoordinateContainer.className = 'GPlocationOriginVisible';
+            this._marker.unbindPopup();
+            this._setLabel();
+            this._clearResults();
+        },
+        onDragMarker: function () {
+            if (!this._marker) {
+                return;
+            }
+            this._activeDragAndDrop = false;
+            this._inputShowPointerContainer.checked = true;
+            var oLatLng = this._marker.getLatLng();
+            this._setCoordinate(oLatLng);
+        },
+        onEndDragMarker: function () {
+            if (!this._marker) {
+                return;
+            }
+            this._inputShowPointerContainer.checked = true;
+            var oLatLng = this._marker.getLatLng();
+            if (this._pressedKeyOnDragAndDrop) {
+                this._setCoordinate(oLatLng);
+            } else {
+                this.onMouseMapClick({ latlng: oLatLng });
+            }
+            this._activeDragAndDrop = false;
+            this._pressedKeyOnDragAndDrop = false;
+        },
+        onMouseDownMarker: function (e) {
+            if (!this._marker) {
+                return;
+            }
+            this._pressedKeyOnDragAndDrop = e.originalEvent.ctrlKey;
+        }
+    });
+    return LocationSelector;
+}(leaflet, {}, gp, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, CommonControlsLocationSelectorDOM, LeafletControlsUtilsPositionFormater, LeafletControlsUtilsIconDefault);
+CommonControlsIsoDOM = function () {
+    var IsoDOM = {
+        _addUID: function (id) {
+            return id + '-' + this._uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPisochron');
+            container.className = 'GPwidget';
+            return container;
+        },
+        _createShowIsoElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowIsochron');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowIsoPictoElement: function () {
+            var context = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowIsochronPicto');
+            label.className = 'GPshowAdvancedToolPicto';
+            label.htmlFor = this._addUID('GPshowIsochron');
+            label.title = 'Calculer une isochrone';
+            if (label.addEventListener) {
+                label.addEventListener('click', function (e) {
+                    context.onShowIsoPanelClick(e);
+                });
+            } else if (label.attachEvent) {
+                label.attachEvent('onclick', function (e) {
+                    context.onShowIsoPanelClick(e);
+                });
+            }
+            var spanOpen = document.createElement('span');
+            spanOpen.id = this._addUID('GPshowIsochronOpen');
+            spanOpen.className = 'GPshowAdvancedToolOpen';
+            label.appendChild(spanOpen);
+            return label;
+        },
+        _createIsoPanelElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronPanel');
+            div.className = 'GPpanel';
+            return div;
+        },
+        _createIsoPanelHeaderElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.className = 'GPpanelHeader';
+            var div = document.createElement('div');
+            div.className = 'GPpanelTitle';
+            div.innerHTML = 'Calcul d\'isochrone';
+            container.appendChild(div);
+            var divClose = document.createElement('div');
+            divClose.id = this._addUID('GPisochronPanelClose');
+            divClose.className = 'GPpanelClose';
+            divClose.title = 'Fermer le panneau';
+            if (divClose.addEventListener) {
+                divClose.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPshowIsochronPicto')).click();
+                }, false);
+            } else if (divClose.attachEvent) {
+                divClose.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPshowIsochronPicto')).click();
+                });
+            }
+            container.appendChild(divClose);
+            return container;
+        },
+        _createIsoPanelFormElement: function () {
+            var self = this;
+            var form = document.createElement('form');
+            form.id = this._addUID('GPisochronForm');
+            form.addEventListener('submit', function (e) {
+                e.preventDefault();
+                self.onIsoComputationSubmit(e);
+                return false;
+            });
+            return form;
+        },
+        _createIsoWaitingElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronCalcWaitingContainer');
+            div.className = 'GPisochronCalcWaitingContainerHidden';
+            var p = document.createElement('p');
+            p.className = 'GPisochronCalcWaiting';
+            p.innerHTML = 'Calcul en cours...';
+            div.appendChild(p);
+            return div;
+        },
+        _createIsoPanelFormTypeChoiceElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronChoice');
+            return div;
+        },
+        _createIsoPanelFormTypeChoiceChronElement: function (checked) {
+            var self = this;
+            var div = document.createElement('div');
+            div.className = 'GPisochronChoiceAlt';
+            var input = document.createElement('input');
+            input.id = this._addUID('GPisochronChoiceAltChron');
+            input.name = 'GPisochronChoiceMode';
+            input.type = 'radio';
+            input.checked = checked ? true : false;
+            if (input.addEventListener) {
+                input.addEventListener('change', function (e) {
+                    document.getElementById(self._addUID('GPisochronValueChron')).className = 'GPflexInput';
+                    document.getElementById(self._addUID('GPisochronValueDist')).className = 'GPisochronValueHidden';
+                    self.onIsoTypeChoiceChange(e);
+                }, false);
+            } else if (input.attachEvent) {
+                input.attachEvent('onchange', function () {
+                    document.getElementById(self._addUID('GPisochronValueChron')).className = 'GPflexInput';
+                    document.getElementById(self._addUID('GPisochronValueDist')).className = 'GPisochronValueHidden';
+                    self.onIsoTypeChoiceChange();
+                });
+            }
+            input.value = 'isochron';
+            div.appendChild(input);
+            var label = document.createElement('label');
+            label.className = 'GPisochronChoiceAltImg';
+            label.htmlFor = this._addUID('GPisochronChoiceAltChron');
+            div.appendChild(label);
+            var span = document.createElement('span');
+            span.id = this._addUID('GPisochronChoiceAltChronTxt');
+            span.innerHTML = 'isochrone';
+            if (span.addEventListener) {
+                span.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPisochronChoiceAltChron')).click();
+                }, false);
+            } else if (span.attachEvent) {
+                span.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPisochronChoiceAltChron')).click();
+                });
+            }
+            div.appendChild(span);
+            return div;
+        },
+        _createIsoPanelFormTypeChoiceDistElement: function (checked) {
+            var self = this;
+            var div = document.createElement('div');
+            div.className = 'GPisochronChoiceAlt';
+            var input = document.createElement('input');
+            input.id = this._addUID('GPisochronChoiceAltDist');
+            input.name = 'GPisochronChoiceMode';
+            input.type = 'radio';
+            input.checked = checked ? true : false;
+            if (input.addEventListener) {
+                input.addEventListener('change', function (e) {
+                    document.getElementById(self._addUID('GPisochronValueDist')).className = 'GPflexInput';
+                    document.getElementById(self._addUID('GPisochronValueChron')).className = 'GPisochronValueHidden';
+                    self.onIsoTypeChoiceChange(e);
+                }, false);
+            } else if (input.attachEvent) {
+                input.attachEvent('onchange', function () {
+                    document.getElementById(self._addUID('GPisochronValueDist')).className = 'GPflexInput';
+                    document.getElementById(self._addUID('GPisochronValueChron')).className = 'GPisochronValueHidden';
+                    self.onIsoTypeChoiceChange();
+                });
+            }
+            input.value = 'isodistance';
+            div.appendChild(input);
+            var label = document.createElement('label');
+            label.className = 'GPisochronChoiceAltImg';
+            label.htmlFor = this._addUID('GPisochronChoiceAltDist');
+            div.appendChild(label);
+            var span = document.createElement('span');
+            span.id = this._addUID('GPisochronChoiceAltDistTxt');
+            span.innerHTML = 'isodistance';
+            if (span.addEventListener) {
+                span.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPisochronChoiceAltDist')).click();
+                }, false);
+            } else if (span.attachEvent) {
+                span.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPisochronChoiceAltDist')).click();
+                });
+            }
+            div.appendChild(span);
+            return div;
+        },
+        _createIsoPanelFormValueIsochronElement: function (checked) {
+            var context = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronValueChron');
+            div.className = checked ? 'GPflexInput' : 'GPisochronValueHidden';
+            var label = document.createElement('label');
+            label.id = this._addUID('GPisochronValueChronLabel');
+            label.htmlFor = this._addUID('GPisochronValueChronInput');
+            label.innerHTML = 'Temps';
+            div.appendChild(label);
+            var input1 = document.createElement('input');
+            input1.id = this._addUID('GPisochronValueChronInput1');
+            input1.min = '0';
+            input1.step = '1';
+            input1.value = '0';
+            input1.type = 'number';
+            if (input1.addEventListener) {
+                input1.addEventListener('change', function (e) {
+                    if (typeof context.onIsoValueChronTimeMinuteChange === 'function') {
+                        context.onIsoValueChronTimeHourChange(e);
+                    }
+                });
+            } else if (input1.attachEvent) {
+                input1.attachEvent('onchange', function (e) {
+                    if (typeof context.onIsoValueChronTimeMinuteChange === 'function') {
+                        context.onIsoValueChronTimeHourChange(e);
+                    }
+                });
+            }
+            div.appendChild(input1);
+            var label1 = document.createElement('label');
+            label1.innerHTML = 'h';
+            div.appendChild(label1);
+            var input2 = document.createElement('input');
+            input2.id = this._addUID('GPisochronValueChronInput2');
+            input2.min = '0';
+            input2.max = '59';
+            input2.step = '1';
+            input2.value = '0';
+            input2.type = 'number';
+            if (input2.addEventListener) {
+                input2.addEventListener('change', function (e) {
+                    if (typeof context.onIsoValueChronTimeMinuteChange === 'function') {
+                        context.onIsoValueChronTimeMinuteChange(e);
+                    }
+                });
+            } else if (input2.attachEvent) {
+                input2.attachEvent('onchange', function (e) {
+                    if (typeof context.onIsoValueChronTimeMinuteChange === 'function') {
+                        context.onIsoValueChronTimeMinuteChange(e);
+                    }
+                });
+            }
+            div.appendChild(input2);
+            var label2 = document.createElement('label');
+            label2.innerHTML = 'min';
+            div.appendChild(label2);
+            return div;
+        },
+        _createIsoPanelFormValueIsodistanceElement: function (checked) {
+            var context = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronValueDist');
+            div.className = checked ? 'GPflexInput' : 'GPisochronValueHidden';
+            var label = document.createElement('label');
+            label.id = this._addUID('GPisochronValueDistLabel');
+            label.htmlFor = this._addUID('GPisochronValueDistInput');
+            label.innerHTML = 'Distance';
+            div.appendChild(label);
+            var input1 = document.createElement('input');
+            input1.id = this._addUID('GPisochronValueDistInput');
+            input1.min = '0';
+            input1.step = 'any';
+            input1.value = '0';
+            input1.type = 'number';
+            if (input1.addEventListener) {
+                input1.addEventListener('change', function (e) {
+                    if (typeof context.onIsoValueDistChange === 'function') {
+                        context.onIsoValueDistChange(e);
+                    }
+                });
+            } else if (input1.attachEvent) {
+                input1.attachEvent('onchange', function (e) {
+                    if (typeof context.onIsoValueDistChange === 'function') {
+                        context.onIsoValueDistChange(e);
+                    }
+                });
+            }
+            div.appendChild(input1);
+            var label1 = document.createElement('label');
+            label1.innerHTML = 'km';
+            div.appendChild(label1);
+            return div;
+        },
+        _createIsoPanelFormModeChoiceElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronModeChoice');
+            return div;
+        },
+        _createIsoPanelFormModeChoiceTransportElement: function (transports) {
+            var context = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronTransportChoice');
+            var span = document.createElement('span');
+            span.className = 'GPisochronModeLabel';
+            span.innerHTML = 'Mode de transport';
+            div.appendChild(span);
+            for (var i = 0; i < transports.length; i++) {
+                var transport = transports[i];
+                if (transport === 'Voiture') {
+                    var inputCar = document.createElement('input');
+                    inputCar.id = this._addUID('GPisochronTransportCar');
+                    inputCar.type = 'radio';
+                    inputCar.name = 'GPisochronTransport';
+                    if (i === 0) {
+                        inputCar.checked = true;
+                    }
+                    if (inputCar.addEventListener) {
+                        inputCar.addEventListener('change', function (e) {
+                            context.onIsoModeTransportChange(e);
+                        });
+                    } else if (inputCar.attachEvent) {
+                        inputCar.attachEvent('onchange', function (e) {
+                            context.onIsoModeTransportChange(e);
+                        });
+                    }
+                    inputCar.value = 'Voiture';
+                    div.appendChild(inputCar);
+                    var labelCar = document.createElement('label');
+                    labelCar.className = 'GPisochronTransportImg';
+                    labelCar.htmlFor = this._addUID('GPisochronTransportCar');
+                    labelCar.title = 'Voiture';
+                    div.appendChild(labelCar);
+                }
+                if (transport === 'Pieton') {
+                    var inputPedestrian = document.createElement('input');
+                    inputPedestrian.id = this._addUID('GPisochronTransportPedestrian');
+                    inputPedestrian.type = 'radio';
+                    inputPedestrian.name = 'GPisochronTransport';
+                    if (i === 0) {
+                        inputPedestrian.checked = true;
+                    }
+                    if (inputPedestrian.addEventListener) {
+                        inputPedestrian.addEventListener('change', function (e) {
+                            context.onIsoModeTransportChange(e);
+                        });
+                    } else if (inputPedestrian.attachEvent) {
+                        inputPedestrian.attachEvent('onchange', function (e) {
+                            context.onIsoModeTransportChange(e);
+                        });
+                    }
+                    inputPedestrian.value = 'Pieton';
+                    div.appendChild(inputPedestrian);
+                    var labelPedestrian = document.createElement('label');
+                    labelPedestrian.className = 'GPisochronTransportImg';
+                    labelPedestrian.htmlFor = this._addUID('GPisochronTransportPedestrian');
+                    labelPedestrian.title = 'Piéton';
+                    div.appendChild(labelPedestrian);
+                }
+            }
+            return div;
+        },
+        _createIsoPanelFormModeChoiceDirectionElement: function (directions) {
+            var self = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisochronDirectionChoice');
+            var span = document.createElement('span');
+            span.className = 'GPisochronModeLabel';
+            span.innerHTML = 'Sens de parcours';
+            div.appendChild(span);
+            var select = document.createElement('select');
+            select.id = this._addUID('GPisochronDirectionSelect');
+            select.className = 'GPinputSelect';
+            select.addEventListener('change', function (e) {
+                self.onIsoModeDirectionChange(e);
+            });
+            for (var i = 0; i < directions.length; i++) {
+                var direction = directions[i];
+                if (direction.toLowerCase() === 'departure') {
+                    var departureOption = document.createElement('option');
+                    if (i === 0) {
+                        departureOption.selected = 'selected';
+                    }
+                    departureOption.value = 'departure';
+                    departureOption.text = 'Départ';
+                    select.appendChild(departureOption);
+                }
+                if (direction.toLowerCase() === 'arrival') {
+                    var arrivalOption = document.createElement('option');
+                    if (i === 0) {
+                        arrivalOption.selected = 'selected';
+                    }
+                    arrivalOption.value = 'arrival';
+                    arrivalOption.text = 'Arrivée';
+                    select.appendChild(arrivalOption);
+                }
+            }
+            div.appendChild(select);
+            return div;
+        },
+        _createShowIsoExclusionsElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowIsoExclusions');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowIsoExclusionsPictoElement: function () {
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowIsoExclusionsPicto');
+            label.className = 'GPshowMoreOptions GPshowIsoExclusionsPicto';
+            label.htmlFor = this._addUID('GPshowIsoExclusions');
+            label.title = 'Exclusions';
+            label.style.top = '240px';
+            return label;
+        },
+        _createIsoPanelFormExclusionsElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPisoExclusions');
+            var span = document.createElement('span');
+            span.className = 'GPisoExclusionsLabel';
+            span.innerHTML = 'Passages autorisés';
+            div.appendChild(span);
+            return div;
+        },
+        _createIsoPanelFormExclusionOptionsElement: function (exclusions) {
+            var context = this;
+            var div = document.createElement('div');
+            div.className = 'GPisoExclusionsOptions';
+            for (var value in exclusions) {
+                if (exclusions.hasOwnProperty(value)) {
+                    var status = exclusions[value];
+                    switch (value) {
+                    case 'toll':
+                        var inputToll = document.createElement('input');
+                        inputToll.id = this._addUID('GPisoExclusionsToll');
+                        inputToll.type = 'checkbox';
+                        inputToll.checked = !status;
+                        if (inputToll.addEventListener) {
+                            inputToll.addEventListener('change', function (e) {
+                                context.onIsoExclusionsChange(e);
+                            });
+                        } else if (inputToll.attachEvent) {
+                            inputToll.attachEvent('onchange', function (e) {
+                                context.onIsoExclusionsChange(e);
+                            });
+                        }
+                        inputToll.value = 'Toll';
+                        div.appendChild(inputToll);
+                        var labelToll = document.createElement('label');
+                        labelToll.className = 'GPisoExclusionsOption';
+                        labelToll.htmlFor = this._addUID('GPisoExclusionsToll');
+                        labelToll.innerHTML = 'Péages';
+                        div.appendChild(labelToll);
+                        break;
+                    case 'tunnel':
+                        var inputTunnel = document.createElement('input');
+                        inputTunnel.id = this._addUID('GPisoExclusionsTunnel');
+                        inputTunnel.type = 'checkbox';
+                        inputTunnel.checked = !status;
+                        if (inputTunnel.addEventListener) {
+                            inputTunnel.addEventListener('change', function (e) {
+                                context.onIsoExclusionsChange(e);
+                            });
+                        } else if (inputTunnel.attachEvent) {
+                            inputTunnel.attachEvent('onchange', function (e) {
+                                context.onIsoExclusionsChange(e);
+                            });
+                        }
+                        inputTunnel.value = 'Tunnel';
+                        div.appendChild(inputTunnel);
+                        var labelTunnel = document.createElement('label');
+                        labelTunnel.className = 'GPisoExclusionsOption';
+                        labelTunnel.htmlFor = this._addUID('GPisoExclusionsTunnel');
+                        labelTunnel.innerHTML = 'Tunnels';
+                        div.appendChild(labelTunnel);
+                        break;
+                    case 'bridge':
+                        var inputBridge = document.createElement('input');
+                        inputBridge.id = this._addUID('GPisoExclusionsBridge');
+                        inputBridge.type = 'checkbox';
+                        inputBridge.checked = !status;
+                        if (inputBridge.addEventListener) {
+                            inputBridge.addEventListener('change', function (e) {
+                                context.onIsoExclusionsChange(e);
+                            });
+                        } else if (inputBridge.attachEvent) {
+                            inputBridge.attachEvent('onchange', function (e) {
+                                context.onIsoExclusionsChange(e);
+                            });
+                        }
+                        inputBridge.value = 'Bridge';
+                        div.appendChild(inputBridge);
+                        var labelBridge = document.createElement('label');
+                        labelBridge.className = 'GPisoExclusionsOption';
+                        labelBridge.htmlFor = this._addUID('GPisoExclusionsBridge');
+                        labelBridge.innerHTML = 'Ponts';
+                        div.appendChild(labelBridge);
+                        break;
+                    }
+                }
+            }
+            return div;
+        },
+        _createIsoSubmitFormElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPisochronSubmit');
+            input.className = 'GPinputSubmit';
+            input.type = 'submit';
+            input.value = 'Calculer';
+            return input;
+        },
+        _createIsoFormResetElement: function () {
+            var self = this;
+            var divReset = document.createElement('div');
+            divReset.id = this._addUID('GPisochronReset');
+            divReset.title = 'Réinitialiser les paramètres';
+            divReset.addEventListener('click', function (e) {
+                self.onIsoResetClick(e);
+            });
+            return divReset;
+        }
+    };
+    return IsoDOM;
+}();
+LeafletControlsIsocurve = function (L, woodman, Gp, RightManagement, ID, LocationSelector, IsoDOM) {
+    var Isocurve = L.Control.extend({
+        includes: IsoDOM,
+        options: {
+            position: 'topleft',
+            collapsed: true,
+            methods: [
+                'time',
+                'distance'
+            ],
+            graphs: [
+                'Voiture',
+                'Pieton'
+            ],
+            exclusions: {
+                toll: false,
+                tunnel: false,
+                bridge: false
+            },
+            directions: [
+                'departure',
+                'arrival'
+            ],
+            disableReverse: false,
+            isocurveOptions: {},
+            autocompleteOptions: {}
+        },
+        initialize: function (options) {
+            L.Util.setOptions(this, options);
+            this._uid = ID.generate();
+            this._isDesktop = this._detectSupport();
+            this._waitingContainer = null;
+            this._showContainer = null;
+            this._formContainer = null;
+            this._submitContainer = null;
+            this._currentTransport = null;
+            this._currentDirection = null;
+            this._currentComputation = null;
+            this._currentTimeHour = 0;
+            this._currentTimeMinute = 0;
+            this._currentDistance = 0;
+            this._currentExclusions = [];
+            this._initTransport();
+            this._initComputation();
+            this._initDirection();
+            this._initExclusions();
+            this._currentPoint = null;
+            this._geojsonIso = null;
+            this._waiting = false;
+            this._timer = null;
+            this._currentIsoResults = null;
+            this._resources = {};
+            this._noRightManagement = false;
+            this._checkRightsManagement();
+        },
+        onAdd: function (map) {
+            var container = this._container = this._initLayout(map);
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            return container;
+        },
+        onRemove: function () {
+        },
+        _initTransport: function () {
+            this._currentTransport = 'Voiture';
+            var transport = this.options.graphs;
+            if (!transport || transport.length === 0) {
+                this.options.graphs = [
+                    'Voiture',
+                    'Pieton'
+                ];
+            }
+            if (L.Util.isArray(transport) && transport.length) {
+                if (transport[0] === 'Voiture' || transport[0] === 'Pieton') {
+                    this._currentTransport = transport[0];
+                }
+            }
+            var serviceOptions = this.options.isocurveOptions;
+            if (serviceOptions.graph) {
+                this._currentTransport = serviceOptions.graph;
+            }
+        },
+        _initDirection: function () {
+            this._currentDirection = 'departure';
+            var directions = this.options.directions;
+            if (!directions || directions.length === 0) {
+                this.options.directions = [
+                    'departure',
+                    'arrival'
+                ];
+            }
+            if (L.Util.isArray(directions) && directions.length) {
+                if (directions[0] === 'departure' || directions[0] === 'arrival') {
+                    this._currentDirection = directions[0];
+                }
+            }
+            var serviceOptions = this.options.isocurveOptions;
+            if (!serviceOptions.reverse) {
+                this._currentDirection = 'departure';
+            }
+            if (serviceOptions.reverse === true) {
+                this._currentDirection = 'arrival';
+                this.options.directions = [
+                    'arrival',
+                    'departure'
+                ];
+            }
+        },
+        _initComputation: function () {
+            this._currentComputation = 'time';
+            var methods = this.options.methods;
+            if (!methods || methods.length === 0) {
+                this.options.methods = [
+                    'time',
+                    'distance'
+                ];
+            }
+            if (L.Util.isArray(methods) && methods.length) {
+                if (methods[0] === 'time' || methods[0] === 'distance') {
+                    this._currentComputation = methods[0];
+                }
+            }
+            var serviceOptions = this.options.isocurveOptions;
+            if (serviceOptions.method) {
+                this._currentComputation = serviceOptions.method;
+            }
+            if (serviceOptions.time) {
+                this._currentComputation = 'time';
+            }
+            if (serviceOptions.distance) {
+                this._currentComputation = 'distance';
+            }
+        },
+        _initExclusions: function () {
+            this._currentExclusions = [];
+            var exclusion = this.options.exclusions;
+            if (!exclusion || typeof exclusion === 'object' && Object.keys(exclusion).length === 0) {
+                this.options.exclusions = {
+                    toll: false,
+                    tunnel: false,
+                    bridge: false
+                };
+            }
+            if (exclusion && typeof exclusion === 'object' && Object.keys(exclusion).length) {
+                for (var k in exclusion) {
+                    if (exclusion.hasOwnProperty(k)) {
+                        if (exclusion.k) {
+                            this._currentExclusions.push(k);
+                        }
+                    }
+                }
+            }
+            var serviceOptions = this.options.isocurveOptions;
+            if (Array.isArray(serviceOptions.exclusions)) {
+                this._currentExclusions = serviceOptions.exclusions;
+            }
+        },
+        _checkRightsManagement: function () {
+            var _opts = null;
+            var _res = [];
+            var _key = null;
+            _key = this.options.isocurveOptions.apiKey;
+            _opts = this.options.isocurveOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = [
+                    'Voiture',
+                    'Pieton'
+                ];
+            }
+            var rightManagementIsochrone = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['Isochrone']
+            });
+            _key = this.options.autocompleteOptions.apiKey;
+            _opts = this.options.autocompleteOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = [
+                    'PositionOfInterest',
+                    'StreetAddress'
+                ];
+            }
+            var rightManagementAutoComplete = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['AutoCompletion']
+            });
+            if (!rightManagementIsochrone && !rightManagementAutoComplete) {
+                this._noRightManagement = true;
+            }
+            if (rightManagementAutoComplete) {
+                this._resources['AutoCompletion'] = {};
+                this._resources['AutoCompletion']['resources'] = rightManagementAutoComplete['AutoCompletion'];
+                this._resources['AutoCompletion']['key'] = rightManagementAutoComplete['key'];
+            }
+            if (rightManagementIsochrone) {
+                this._resources['Isochrone'] = {};
+                this._resources['Isochrone']['resources'] = rightManagementIsochrone['Isochrone'];
+                this._resources['Isochrone']['key'] = rightManagementIsochrone['key'];
+            }
+        },
+        _detectSupport: function () {
+            var isDesktop = true;
+            var userAgent = window.navigator.userAgent.toLowerCase();
+            if (userAgent.indexOf('iphone') !== -1 || userAgent.indexOf('ipod') !== -1 || userAgent.indexOf('ipad') !== -1 || userAgent.indexOf('android') !== -1 || userAgent.indexOf('mobile') !== -1 || userAgent.indexOf('blackberry') !== -1 || userAgent.indexOf('tablet') !== -1 || userAgent.indexOf('phone') !== -1 || userAgent.indexOf('touch') !== -1) {
+                isDesktop = false;
+            }
+            if (userAgent.indexOf('msie') !== -1 || userAgent.indexOf('trident') !== -1) {
+                isDesktop = true;
+            }
+            return isDesktop;
+        },
+        _initLayout: function (map) {
+            var container = this._createMainContainerElement();
+            var inputShow = this._showContainer = this._createShowIsoElement();
+            container.appendChild(inputShow);
+            if (!this.options.collapsed) {
+                inputShow.checked = true;
+            }
+            var picto = this._createShowIsoPictoElement();
+            container.appendChild(picto);
+            var panel = this._createIsoPanelElement();
+            var header = this._createIsoPanelHeaderElement();
+            panel.appendChild(header);
+            var form = this._formContainer = this._createIsoPanelFormElement();
+            var point = this._createIsoPanelFormPointElement(map);
+            form.appendChild(point);
+            var isoChronChecked = false;
+            var isoDistChecked = false;
+            var typeChoice = this._createIsoPanelFormTypeChoiceElement();
+            for (var i = 0; i < this.options.methods.length; i++) {
+                if (this.options.methods[i] === 'time') {
+                    isoChronChecked = i === 0 ? true : false;
+                    typeChoice.appendChild(this._createIsoPanelFormTypeChoiceChronElement(isoChronChecked));
+                }
+                if (this.options.methods[i] === 'distance') {
+                    isoDistChecked = i === 0 ? true : false;
+                    typeChoice.appendChild(this._createIsoPanelFormTypeChoiceDistElement(isoDistChecked));
+                }
+            }
+            form.appendChild(typeChoice);
+            form.appendChild(this._createIsoPanelFormValueIsochronElement(isoChronChecked));
+            form.appendChild(this._createIsoPanelFormValueIsodistanceElement(isoDistChecked));
+            var modeChoice = this._createIsoPanelFormModeChoiceElement();
+            modeChoice.appendChild(this._createIsoPanelFormModeChoiceTransportElement(this.options.graphs));
+            modeChoice.appendChild(this._createIsoPanelFormModeChoiceDirectionElement(this.options.directions));
+            form.appendChild(modeChoice);
+            if (this.options.exclusions && typeof this.options.exclusions === 'object' && Object.keys(this.options.exclusions).length !== 0) {
+                form.appendChild(this._createShowIsoExclusionsElement());
+                form.appendChild(this._createShowIsoExclusionsPictoElement());
+                var exclusion = this._createIsoPanelFormExclusionsElement();
+                exclusion.appendChild(this._createIsoPanelFormExclusionOptionsElement(this.options.exclusions));
+                form.appendChild(exclusion);
+            }
+            var divReset = this._createIsoFormResetElement();
+            form.appendChild(divReset);
+            var submit = this._submitContainer = this._createIsoSubmitFormElement();
+            form.appendChild(submit);
+            panel.appendChild(form);
+            var waiting = this._waitingContainer = this._createIsoWaitingElement();
+            panel.appendChild(waiting);
+            container.appendChild(panel);
+            return container;
+        },
+        _createIsoPanelFormPointElement: function (map) {
+            this._currentPoint = new LocationSelector({
+                apiKey: this.options.apiKey || null,
+                tag: {
+                    id: 0,
+                    unique: this._uid,
+                    label: 'Départ',
+                    color: 'red',
+                    display: true
+                },
+                displayInfo: true,
+                disableReverse: this.options.disableReverse,
+                autocompleteOptions: this.options.autocompleteOptions || null
+            });
+            this._currentPoint.setMap(map);
+            return this._currentPoint.getContainer();
+        },
+        onShowIsoPanelClick: function (e) {
+        },
+        onIsoResetClick: function (e) {
+            this._clear();
+        },
+        onIsoTypeChoiceChange: function (e) {
+            var value = e.target.value;
+            if (!value) {
+                return;
+            }
+            if (value === 'isodistance') {
+                this._currentComputation = 'distance';
+            }
+            if (value === 'isochron') {
+                this._currentComputation = 'time';
+            }
+        },
+        onIsoModeTransportChange: function (e) {
+            var value = e.target.value;
+            if (!value) {
+                return;
+            }
+            this._currentTransport = value;
+        },
+        onIsoModeDirectionChange: function (e) {
+            var value = e.target.value;
+            if (!value) {
+                return;
+            }
+            this._currentDirection = value;
+        },
+        onIsoValueChronTimeHourChange: function (e) {
+            var value = e.target.value;
+            this._timeHourContainer = e.target;
+            if (!value) {
+                return;
+            }
+            this._currentTimeHour = value;
+        },
+        onIsoValueChronTimeMinuteChange: function (e) {
+            var value = e.target.value;
+            this._timeMinuteContainer = e.target;
+            if (!value) {
+                return;
+            }
+            this._currentTimeMinute = value;
+        },
+        onIsoValueDistChange: function (e) {
+            var value = e.target.value;
+            this._distanceContainer = e.target;
+            if (!value) {
+                return;
+            }
+            this._currentDistance = value;
+        },
+        onIsoExclusionsChange: function (e) {
+            var value = e.target.value;
+            var checked = e.target.checked;
+            if (!value) {
+                return;
+            }
+            var bFound = false;
+            var iFound = null;
+            for (var i = 0; i < this._currentExclusions.length; i++) {
+                if (this._currentExclusions[i] === value) {
+                    iFound = i;
+                    bFound = true;
+                }
+            }
+            if (!bFound && !checked) {
+                this._currentExclusions.push(value);
+            }
+            if (bFound && checked) {
+                this._currentExclusions.splice(iFound, 1);
+            }
+        },
+        onIsoComputationSubmit: function () {
+            if (!this._currentPoint || !this._currentPoint.getCoordinate || !this._currentPoint.getCoordinate()) {
+                return;
+            }
+            var time;
+            if (this._currentComputation.toLowerCase() === 'time') {
+                time = this._currentTimeHour * 3600 + this._currentTimeMinute * 60;
+            }
+            var distance;
+            if (this._currentComputation.toLowerCase() === 'distance') {
+                distance = this._currentDistance * 1000;
+            }
+            if (!time && !distance) {
+                return;
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            this._displayWaitingContainer();
+            var self = this;
+            this._requestIsoCurve({
+                position: self._currentPoint.getCoordinate(),
+                graph: self._currentTransport,
+                exclusions: self._currentExclusions,
+                method: self._currentComputation,
+                reverse: self._currentDirection.toLowerCase() === 'arrival' ? true : false,
+                time: time,
+                distance: distance,
+                smoothing: true,
+                timeout: 7000,
+                protocol: 'XHR',
+                onSuccess: function (results) {
+                    if (results) {
+                        self._drawIsoResults(results);
+                    }
+                },
+                onFailure: function (error) {
+                    self._hideWaitingContainer();
+                    self._clearIsoResultsGeometry();
+                }
+            });
+        },
+        _requestIsoCurve: function (settings) {
+            if (!settings || typeof settings === 'object' && Object.keys(settings).length === 0) {
+                return;
+            }
+            if (!settings.position) {
+                return;
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            var services = this._resources['Isochrone'];
+            if (!services) {
+                return;
+            }
+            var resources = services.resources;
+            if (!resources || typeof resources === 'object' && Object.keys(resources).length === 0) {
+                return;
+            }
+            var options = {};
+            L.Util.extend(options, settings);
+            L.Util.extend(options, this.options.isocurveOptions);
+            var bFound = false;
+            for (var i = 0; i < resources.length; i++) {
+                if (resources[i] === options.graph) {
+                    bFound = true;
+                }
+            }
+            if (!bFound) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            var key = this._resources['Isochrone']['key'];
+            options.apiKey = this.options.isocurveOptions.apiKey || this.options.apiKey || key;
+            Gp.Services.isoCurve(options);
+        },
+        _drawIsoResults: function (results) {
+            this._clearIsoResultsGeometry();
+            this._currentIsoResults = results;
+            if (!results.geometry) {
+                this._hideWaitingContainer();
+                return;
+            }
+            var map = this._map;
+            var _geometry = results.geometry;
+            var _style = {
+                color: '#ff7800',
+                weight: 5,
+                opacity: 0.65
+            };
+            this._geojsonIso = L.geoJson(_geometry, { style: _style }).addTo(map);
+            this._hideWaitingContainer();
+            this._formContainer.className = 'GPisochroComponentHidden';
+        },
+        _clear: function () {
+            this._initTransport();
+            this._initExclusions();
+            this._initComputation();
+            this._initDirection();
+            this._currentIsoResults = null;
+            this._clearIsoResultsGeometry();
+            this._currentPoint.clear();
+            if (this._timeHourContainer) {
+                this._timeHourContainer.value = 0;
+            }
+            if (this._timeMinuteContainer) {
+                this._timeMinuteContainer.value = 0;
+            }
+            if (this._distanceContainer) {
+                this._distanceContainer.value = 0;
+            }
+        },
+        _clearIsoResultsGeometry: function () {
+            var map = this._map;
+            if (this._geojsonIso != null) {
+                map.removeLayer(this._geojsonIso);
+                this._geojsonIso = null;
+            }
+        },
+        _displayWaitingContainer: function () {
+            this._waitingContainer.className = 'GPisochronCalcWaitingContainerVisible';
+            this._waiting = true;
+            if (this._timer) {
+                clearTimeout(this._timer);
+                this._timer = null;
+            }
+            var context = this;
+            this._timer = setTimeout(function () {
+                if (context._waiting === true) {
+                    context._hideWaitingContainer();
+                } else {
+                    if (context._timer) {
+                        clearTimeout(context._timer);
+                    }
+                }
+            }, 16000);
+        },
+        _hideWaitingContainer: function () {
+            if (this._waiting) {
+                this._waitingContainer.className = 'GPisochronCalcWaitingContainerHidden';
+                this._waiting = false;
+                clearTimeout(this._timer);
+                this._timer = null;
+            }
+        }
+    });
+    return Isocurve;
+}(leaflet, {}, gp, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, LeafletControlsLocationSelector, CommonControlsIsoDOM);
+CommonControlsMousePositionDOM = function () {
+    var MousePositionDOM = {
+        _addUID: function (id) {
+            var uid = this._uid ? id + '-' + this._uid : id;
+            return uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPmousePosition');
+            container.className = 'GPwidget';
+            return container;
+        },
+        _createShowMousePositionElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowMousePosition');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowMousePositionPictoElement: function (isDesktop) {
+            var self = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowMousePositionPicto');
+            label.className = 'GPshowAdvancedToolPicto';
+            label.htmlFor = this._addUID('GPshowMousePosition');
+            label.title = 'Afficher les coordonnées du curseur';
+            label.addEventListener('click', function (e) {
+                var mapCenterClass = '';
+                if (!document.getElementById(self._addUID('GPshowMousePosition')).checked && !isDesktop) {
+                    mapCenterClass = 'GPmapCenterVisible';
+                }
+                document.getElementById('GPmapCenter').className = mapCenterClass;
+                self.onShowMousePositionClick(e);
+            });
+            var spanOpen = document.createElement('span');
+            spanOpen.id = this._addUID('GPshowMousePositionOpen');
+            spanOpen.className = 'GPshowAdvancedToolOpen';
+            label.appendChild(spanOpen);
+            return label;
+        },
+        _createMousePositionPanelElement: function (displayAltitude, displayCoordinates) {
+            displayAltitude = displayAltitude ? true : typeof displayAltitude === 'undefined' ? true : false;
+            displayCoordinates = displayCoordinates ? true : typeof displayCoordinates === 'undefined' ? true : false;
+            var div = document.createElement('div');
+            div.id = this._addUID('GPmousePositionPanel');
+            div.className = 'GPpanel';
+            div.appendChild(this._createMousePositionPanelHeaderElement());
+            div.appendChild(this._createMousePositionPanelBasicElement(displayAltitude, displayCoordinates));
+            var arraySettings = this._createShowMousePositionSettingsElement(displayCoordinates);
+            for (var j = 0; j < arraySettings.length; j++) {
+                div.appendChild(arraySettings[j]);
+            }
+            return div;
+        },
+        _createMapCenter: function () {
+            var div = document.createElement('div');
+            div.id = 'GPmapCenter';
+            div.className = '';
+            return div;
+        },
+        _createMousePositionPanelHeaderElement: function () {
+            var container = document.createElement('div');
+            container.className = 'GPpanelHeader';
+            var divTitle = document.createElement('div');
+            divTitle.className = 'GPpanelTitle';
+            divTitle.innerHTML = 'Coordonnées';
+            container.appendChild(divTitle);
+            var divClose = document.createElement('div');
+            divClose.id = 'GPmousePositionPanelClose';
+            divClose.className = 'GPpanelClose';
+            divClose.title = 'Fermer le panneau';
+            var self = this;
+            if (divClose.addEventListener) {
+                divClose.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPshowMousePositionPicto')).click();
+                }, false);
+            } else if (divClose.attachEvent) {
+                divClose.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPshowMousePositionPicto')).click();
+                });
+            }
+            container.appendChild(divClose);
+            return container;
+        },
+        _createMousePositionPanelBasicElement: function (displayAltitude, displayCoordinates) {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPmousePositionBasicPanel');
+            container.appendChild(this._createMousePositionPanelBasicCoordinateElement(displayCoordinates));
+            container.appendChild(this._createMousePositionPanelBasicAltitudeElement(displayAltitude));
+            return container;
+        },
+        _createMousePositionPanelBasicCoordinateElement: function (display) {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPmousePositionCoordinate');
+            div.style.display = display ? 'block' : 'none';
+            var spanLat = document.createElement('span');
+            spanLat.className = 'GPmousePositionLabel';
+            spanLat.id = this._addUID('GPmousePositionLatLabel');
+            spanLat.innerHTML = 'Latitude : ';
+            div.appendChild(spanLat);
+            var spanCLat = document.createElement('span');
+            spanCLat.className = 'GPmousePositionCoords';
+            spanCLat.id = this._addUID('GPmousePositionLat');
+            spanCLat.innerHTML = '';
+            div.appendChild(spanCLat);
+            var spanLon = document.createElement('span');
+            spanLon.className = 'GPmousePositionLabel';
+            spanLon.id = this._addUID('GPmousePositionLonLabel');
+            spanLon.innerHTML = 'Longitude : ';
+            div.appendChild(spanLon);
+            var spanCLon = document.createElement('span');
+            spanCLon.className = 'GPmousePositionCoords';
+            spanCLon.id = this._addUID('GPmousePositionLon');
+            spanCLon.innerHTML = '';
+            div.appendChild(spanCLon);
+            return div;
+        },
+        _createMousePositionPanelBasicAltitudeElement: function (display) {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPmousePositionAltitude');
+            div.style.display = display ? 'block' : 'none';
+            var spanLabel = document.createElement('span');
+            spanLabel.className = 'GPmousePositionLabel';
+            spanLabel.innerHTML = 'Altitude : ';
+            div.appendChild(spanLabel);
+            var spanAlt = document.createElement('span');
+            spanAlt.className = 'GPmousePositionCoords';
+            spanAlt.id = this._addUID('GPmousePositionAlt');
+            spanAlt.innerHTML = '';
+            div.appendChild(spanAlt);
+            return div;
+        },
+        _createShowMousePositionSettingsElement: function (display) {
+            var list = [];
+            var input = document.createElement('input');
+            input.type = 'checkbox';
+            input.id = this._addUID('GPshowMousePositionSettings');
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowMousePositionSettingsPicto');
+            label.htmlFor = this._addUID('GPshowMousePositionSettings');
+            label.title = 'Réglages';
+            label.className = 'GPshowMoreOptions GPshowMousePositionSettingsPicto';
+            label.style.display = display ? 'block' : 'none';
+            list.push(input);
+            list.push(label);
+            return list;
+        },
+        _createMousePositionSettingsElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPmousePositionSettings');
+            var span = document.createElement('span');
+            span.className = 'GPmousePositionSettingsLabel';
+            span.innerHTML = 'Système de référence';
+            container.appendChild(span);
+            return container;
+        },
+        _createMousePositionSettingsSystemsElement: function (systems) {
+            var context = this;
+            var selectSystem = document.createElement('select');
+            selectSystem.id = this._addUID('GPmousePositionProjectionSystem');
+            selectSystem.className = 'GPinputSelect GPmousePositionSettingsSelect';
+            selectSystem.addEventListener('change', function (e) {
+                context.onMousePositionProjectionSystemChange(e);
+            });
+            selectSystem.addEventListener('mouseover', function (e) {
+                context.onMousePositionProjectionSystemMouseOver(e);
+            });
+            for (var i = 0; i < systems.length; i++) {
+                var obj = systems[i];
+                var option = document.createElement('option');
+                option.value = obj.code;
+                option.text = obj.label || i;
+                selectSystem.appendChild(option);
+            }
+            return selectSystem;
+        },
+        _createMousePositionSettingsUnitsElement: function (units) {
+            var context = this;
+            var selectUnits = document.createElement('select');
+            selectUnits.id = this._addUID('GPmousePositionProjectionUnits');
+            selectUnits.className = 'GPinputSelect GPmousePositionSettingsSelect';
+            selectUnits.addEventListener('change', function (e) {
+                context.onMousePositionProjectionUnitsChange(e);
+            });
+            for (var j = 0; j < units.length; j++) {
+                var obj = units[j];
+                var option = document.createElement('option');
+                option.value = obj.code ? obj.code : j;
+                option.text = obj.label || j;
+                selectUnits.appendChild(option);
+            }
+            return selectUnits;
+        },
+        GPdisplayCoords: function (coordinate) {
+            if (coordinate && coordinate != null) {
+                var labelLon = document.getElementById(this._addUID('GPmousePositionLonLabel'));
+                var labelLat = document.getElementById(this._addUID('GPmousePositionLatLabel'));
+                if (coordinate.x || coordinate.y) {
+                    labelLat.innerHTML = 'X : ';
+                    labelLon.innerHTML = 'Y : ';
+                } else if (coordinate.e || coordinate.n) {
+                    labelLat.innerHTML = 'E : ';
+                    labelLon.innerHTML = 'N : ';
+                } else {
+                    labelLat.innerHTML = 'Latitude : ';
+                    labelLon.innerHTML = 'Longitude : ';
+                }
+                var elLat = document.getElementById(this._addUID('GPmousePositionLat'));
+                var elLon = document.getElementById(this._addUID('GPmousePositionLon'));
+                elLat.innerHTML = coordinate.x || coordinate.lat || coordinate.e || '0';
+                if (coordinate.unit) {
+                    elLat.innerHTML += ' ';
+                    elLat.innerHTML += coordinate.unit;
+                }
+                elLon.innerHTML = coordinate.y || coordinate.lng || coordinate.lon || coordinate.n || '0';
+                if (coordinate.unit) {
+                    elLon.innerHTML += ' ';
+                    elLon.innerHTML += coordinate.unit;
+                }
+            }
+        },
+        GPdisplayElevation: function (coordinate, altitudeTimeoutDelay, noDataValue, noDataValueTolerance) {
+            var self = this;
+            var altitudeTimeout;
+            if (!altitudeTimeoutDelay) {
+                altitudeTimeoutDelay = 500;
+            }
+            clearTimeout(altitudeTimeout);
+            document.getElementById(this._addUID('GPmousePositionAlt')).innerHTML = '...';
+            if (noDataValue == null) {
+                noDataValue = -99999;
+            }
+            if (noDataValueTolerance == null) {
+                noDataValueTolerance = 99980;
+            }
+            var maxThreshold = noDataValue + noDataValueTolerance;
+            var minThreshold = noDataValue - noDataValueTolerance;
+            if (coordinate && coordinate != null) {
+                if (document.getElementById(this._addUID('GPmousePositionAltitude'))) {
+                    altitudeTimeout = setTimeout(function () {
+                        self.onRequestAltitude(coordinate, function (z) {
+                            if (minThreshold < z && z < maxThreshold) {
+                                document.getElementById(self._addUID('GPmousePositionAlt')).innerHTML = '--- m';
+                            } else {
+                                document.getElementById(self._addUID('GPmousePositionAlt')).innerHTML = z + ' m';
+                            }
+                        });
+                    }, altitudeTimeoutDelay);
+                }
+            }
+        }
+    };
+    return MousePositionDOM;
+}();
+!function (e) {
+    if ('object' == typeof exports)
+        module.exports = e();
+    else if (true)
+        proj4 = function () {
+            return typeof e === 'function' ? e() : e;
+        }();
+    else {
+        var f;
+        'undefined' != typeof window ? f = window : 'undefined' != typeof global ? f = global : 'undefined' != typeof self && (f = self), f.proj4 = e();
+    }
+}(function () {
+    var define, module, exports;
+    return function e(t, n, r) {
+        function s(o, u) {
+            if (!n[o]) {
+                if (!t[o]) {
+                    var a = typeof require == 'function' && require;
+                    if (!u && a)
+                        return a(o, !0);
+                    if (i)
+                        return i(o, !0);
+                    throw new Error('Cannot find module \'' + o + '\'');
+                }
+                var f = n[o] = { exports: {} };
+                t[o][0].call(f.exports, function (e) {
+                    var n = t[o][1][e];
+                    return s(n ? n : e);
+                }, f, f.exports, e, t, n, r);
+            }
+            return n[o].exports;
+        }
+        var i = typeof require == 'function' && require;
+        for (var o = 0; o < r.length; o++)
+            s(r[o]);
+        return s;
+    }({
+        1: [
+            function (_dereq_, module, exports) {
+                var mgrs = _dereq_('mgrs');
+                function Point(x, y, z) {
+                    if (!(this instanceof Point)) {
+                        return new Point(x, y, z);
+                    }
+                    if (Array.isArray(x)) {
+                        this.x = x[0];
+                        this.y = x[1];
+                        this.z = x[2] || 0;
+                    } else if (typeof x === 'object') {
+                        this.x = x.x;
+                        this.y = x.y;
+                        this.z = x.z || 0;
+                    } else if (typeof x === 'string' && typeof y === 'undefined') {
+                        var coords = x.split(',');
+                        this.x = parseFloat(coords[0], 10);
+                        this.y = parseFloat(coords[1], 10);
+                        this.z = parseFloat(coords[2], 10) || 0;
+                    } else {
+                        this.x = x;
+                        this.y = y;
+                        this.z = z || 0;
+                    }
+                    console.warn('proj4.Point will be removed in version 3, use proj4.toPoint');
+                }
+                Point.fromMGRS = function (mgrsStr) {
+                    return new Point(mgrs.toPoint(mgrsStr));
+                };
+                Point.prototype.toMGRS = function (accuracy) {
+                    return mgrs.forward([
+                        this.x,
+                        this.y
+                    ], accuracy);
+                };
+                module.exports = Point;
+                return exports;
+            },
+            { 'mgrs': 66 }
+        ],
+        2: [
+            function (_dereq_, module, exports) {
+                var parseCode = _dereq_('./parseCode');
+                var extend = _dereq_('./extend');
+                var projections = _dereq_('./projections');
+                var deriveConstants = _dereq_('./deriveConstants');
+                function Projection(srsCode, callback) {
+                    if (!(this instanceof Projection)) {
+                        return new Projection(srsCode);
+                    }
+                    callback = callback || function (error) {
+                        if (error) {
+                            throw error;
+                        }
+                    };
+                    var json = parseCode(srsCode);
+                    if (typeof json !== 'object') {
+                        callback(srsCode);
+                        return;
+                    }
+                    var modifiedJSON = deriveConstants(json);
+                    var ourProj = Projection.projections.get(modifiedJSON.projName);
+                    if (ourProj) {
+                        extend(this, modifiedJSON);
+                        extend(this, ourProj);
+                        this.init();
+                        callback(null, this);
+                    } else {
+                        callback(srsCode);
+                    }
+                }
+                Projection.projections = projections;
+                Projection.projections.start();
+                module.exports = Projection;
+                return exports;
+            },
+            {
+                './deriveConstants': 32,
+                './extend': 33,
+                './parseCode': 36,
+                './projections': 38
+            }
+        ],
+        3: [
+            function (_dereq_, module, exports) {
+                module.exports = function (crs, denorm, point) {
+                    var xin = point.x, yin = point.y, zin = point.z || 0;
+                    var v, t, i;
+                    for (i = 0; i < 3; i++) {
+                        if (denorm && i === 2 && point.z === undefined) {
+                            continue;
+                        }
+                        if (i === 0) {
+                            v = xin;
+                            t = 'x';
+                        } else if (i === 1) {
+                            v = yin;
+                            t = 'y';
+                        } else {
+                            v = zin;
+                            t = 'z';
+                        }
+                        switch (crs.axis[i]) {
+                        case 'e':
+                            point[t] = v;
+                            break;
+                        case 'w':
+                            point[t] = -v;
+                            break;
+                        case 'n':
+                            point[t] = v;
+                            break;
+                        case 's':
+                            point[t] = -v;
+                            break;
+                        case 'u':
+                            if (point[t] !== undefined) {
+                                point.z = v;
+                            }
+                            break;
+                        case 'd':
+                            if (point[t] !== undefined) {
+                                point.z = -v;
+                            }
+                            break;
+                        default:
+                            return null;
+                        }
+                    }
+                    return point;
+                };
+                return exports;
+            },
+            {}
+        ],
+        4: [
+            function (_dereq_, module, exports) {
+                var HALF_PI = Math.PI / 2;
+                var sign = _dereq_('./sign');
+                module.exports = function (x) {
+                    return Math.abs(x) < HALF_PI ? x : x - sign(x) * Math.PI;
+                };
+                return exports;
+            },
+            { './sign': 21 }
+        ],
+        5: [
+            function (_dereq_, module, exports) {
+                var TWO_PI = Math.PI * 2;
+                var sign = _dereq_('./sign');
+                module.exports = function (x) {
+                    return Math.abs(x) < Math.PI ? x : x - sign(x) * TWO_PI;
+                };
+                return exports;
+            },
+            { './sign': 21 }
+        ],
+        6: [
+            function (_dereq_, module, exports) {
+                module.exports = function (x) {
+                    if (Math.abs(x) > 1) {
+                        x = x > 1 ? 1 : -1;
+                    }
+                    return Math.asin(x);
+                };
+                return exports;
+            },
+            {}
+        ],
+        7: [
+            function (_dereq_, module, exports) {
+                module.exports = function (x) {
+                    return 1 - 0.25 * x * (1 + x / 16 * (3 + 1.25 * x));
+                };
+                return exports;
+            },
+            {}
+        ],
+        8: [
+            function (_dereq_, module, exports) {
+                module.exports = function (x) {
+                    return 0.375 * x * (1 + 0.25 * x * (1 + 0.46875 * x));
+                };
+                return exports;
+            },
+            {}
+        ],
+        9: [
+            function (_dereq_, module, exports) {
+                module.exports = function (x) {
+                    return 0.05859375 * x * x * (1 + 0.75 * x);
+                };
+                return exports;
+            },
+            {}
+        ],
+        10: [
+            function (_dereq_, module, exports) {
+                module.exports = function (x) {
+                    return x * x * x * (35 / 3072);
+                };
+                return exports;
+            },
+            {}
+        ],
+        11: [
+            function (_dereq_, module, exports) {
+                module.exports = function (a, e, sinphi) {
+                    var temp = e * sinphi;
+                    return a / Math.sqrt(1 - temp * temp);
+                };
+                return exports;
+            },
+            {}
+        ],
+        12: [
+            function (_dereq_, module, exports) {
+                module.exports = function (ml, e0, e1, e2, e3) {
+                    var phi;
+                    var dphi;
+                    phi = ml / e0;
+                    for (var i = 0; i < 15; i++) {
+                        dphi = (ml - (e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi))) / (e0 - 2 * e1 * Math.cos(2 * phi) + 4 * e2 * Math.cos(4 * phi) - 6 * e3 * Math.cos(6 * phi));
+                        phi += dphi;
+                        if (Math.abs(dphi) <= 1e-10) {
+                            return phi;
+                        }
+                    }
+                    return NaN;
+                };
+                return exports;
+            },
+            {}
+        ],
+        13: [
+            function (_dereq_, module, exports) {
+                var HALF_PI = Math.PI / 2;
+                module.exports = function (eccent, q) {
+                    var temp = 1 - (1 - eccent * eccent) / (2 * eccent) * Math.log((1 - eccent) / (1 + eccent));
+                    if (Math.abs(Math.abs(q) - temp) < 0.000001) {
+                        if (q < 0) {
+                            return -1 * HALF_PI;
+                        } else {
+                            return HALF_PI;
+                        }
+                    }
+                    var phi = Math.asin(0.5 * q);
+                    var dphi;
+                    var sin_phi;
+                    var cos_phi;
+                    var con;
+                    for (var i = 0; i < 30; i++) {
+                        sin_phi = Math.sin(phi);
+                        cos_phi = Math.cos(phi);
+                        con = eccent * sin_phi;
+                        dphi = Math.pow(1 - con * con, 2) / (2 * cos_phi) * (q / (1 - eccent * eccent) - sin_phi / (1 - con * con) + 0.5 / eccent * Math.log((1 - con) / (1 + con)));
+                        phi += dphi;
+                        if (Math.abs(dphi) <= 1e-10) {
+                            return phi;
+                        }
+                    }
+                    return NaN;
+                };
+                return exports;
+            },
+            {}
+        ],
+        14: [
+            function (_dereq_, module, exports) {
+                module.exports = function (e0, e1, e2, e3, phi) {
+                    return e0 * phi - e1 * Math.sin(2 * phi) + e2 * Math.sin(4 * phi) - e3 * Math.sin(6 * phi);
+                };
+                return exports;
+            },
+            {}
+        ],
+        15: [
+            function (_dereq_, module, exports) {
+                module.exports = function (eccent, sinphi, cosphi) {
+                    var con = eccent * sinphi;
+                    return cosphi / Math.sqrt(1 - con * con);
+                };
+                return exports;
+            },
+            {}
+        ],
+        16: [
+            function (_dereq_, module, exports) {
+                var HALF_PI = Math.PI / 2;
+                module.exports = function (eccent, ts) {
+                    var eccnth = 0.5 * eccent;
+                    var con, dphi;
+                    var phi = HALF_PI - 2 * Math.atan(ts);
+                    for (var i = 0; i <= 15; i++) {
+                        con = eccent * Math.sin(phi);
+                        dphi = HALF_PI - 2 * Math.atan(ts * Math.pow((1 - con) / (1 + con), eccnth)) - phi;
+                        phi += dphi;
+                        if (Math.abs(dphi) <= 1e-10) {
+                            return phi;
+                        }
+                    }
+                    return -9999;
+                };
+                return exports;
+            },
+            {}
+        ],
+        17: [
+            function (_dereq_, module, exports) {
+                var C00 = 1;
+                var C02 = 0.25;
+                var C04 = 0.046875;
+                var C06 = 0.01953125;
+                var C08 = 0.01068115234375;
+                var C22 = 0.75;
+                var C44 = 0.46875;
+                var C46 = 0.013020833333333334;
+                var C48 = 0.007120768229166667;
+                var C66 = 0.3645833333333333;
+                var C68 = 0.005696614583333333;
+                var C88 = 0.3076171875;
+                module.exports = function (es) {
+                    var en = [];
+                    en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
+                    en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
+                    var t = es * es;
+                    en[2] = t * (C44 - es * (C46 + es * C48));
+                    t *= es;
+                    en[3] = t * (C66 - es * C68);
+                    en[4] = t * es * C88;
+                    return en;
+                };
+                return exports;
+            },
+            {}
+        ],
+        18: [
+            function (_dereq_, module, exports) {
+                var pj_mlfn = _dereq_('./pj_mlfn');
+                var EPSLN = 1e-10;
+                var MAX_ITER = 20;
+                module.exports = function (arg, es, en) {
+                    var k = 1 / (1 - es);
+                    var phi = arg;
+                    for (var i = MAX_ITER; i; --i) {
+                        var s = Math.sin(phi);
+                        var t = 1 - es * s * s;
+                        t = (pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k;
+                        phi -= t;
+                        if (Math.abs(t) < EPSLN) {
+                            return phi;
+                        }
+                    }
+                    return phi;
+                };
+                return exports;
+            },
+            { './pj_mlfn': 19 }
+        ],
+        19: [
+            function (_dereq_, module, exports) {
+                module.exports = function (phi, sphi, cphi, en) {
+                    cphi *= sphi;
+                    sphi *= sphi;
+                    return en[0] * phi - cphi * (en[1] + sphi * (en[2] + sphi * (en[3] + sphi * en[4])));
+                };
+                return exports;
+            },
+            {}
+        ],
+        20: [
+            function (_dereq_, module, exports) {
+                module.exports = function (eccent, sinphi) {
+                    var con;
+                    if (eccent > 1e-7) {
+                        con = eccent * sinphi;
+                        return (1 - eccent * eccent) * (sinphi / (1 - con * con) - 0.5 / eccent * Math.log((1 - con) / (1 + con)));
+                    } else {
+                        return 2 * sinphi;
+                    }
+                };
+                return exports;
+            },
+            {}
+        ],
+        21: [
+            function (_dereq_, module, exports) {
+                module.exports = function (x) {
+                    return x < 0 ? -1 : 1;
+                };
+                return exports;
+            },
+            {}
+        ],
+        22: [
+            function (_dereq_, module, exports) {
+                module.exports = function (esinp, exp) {
+                    return Math.pow((1 - esinp) / (1 + esinp), exp);
+                };
+                return exports;
+            },
+            {}
+        ],
+        23: [
+            function (_dereq_, module, exports) {
+                module.exports = function (array) {
+                    var out = {
+                        x: array[0],
+                        y: array[1]
+                    };
+                    if (array.length > 2) {
+                        out.z = array[2];
+                    }
+                    if (array.length > 3) {
+                        out.m = array[3];
+                    }
+                    return out;
+                };
+                return exports;
+            },
+            {}
+        ],
+        24: [
+            function (_dereq_, module, exports) {
+                var HALF_PI = Math.PI / 2;
+                module.exports = function (eccent, phi, sinphi) {
+                    var con = eccent * sinphi;
+                    var com = 0.5 * eccent;
+                    con = Math.pow((1 - con) / (1 + con), com);
+                    return Math.tan(0.5 * (HALF_PI - phi)) / con;
+                };
+                return exports;
+            },
+            {}
+        ],
+        25: [
+            function (_dereq_, module, exports) {
+                exports.wgs84 = {
+                    towgs84: '0,0,0',
+                    ellipse: 'WGS84',
+                    datumName: 'WGS84'
+                };
+                exports.ch1903 = {
+                    towgs84: '674.374,15.056,405.346',
+                    ellipse: 'bessel',
+                    datumName: 'swiss'
+                };
+                exports.ggrs87 = {
+                    towgs84: '-199.87,74.79,246.62',
+                    ellipse: 'GRS80',
+                    datumName: 'Greek_Geodetic_Reference_System_1987'
+                };
+                exports.nad83 = {
+                    towgs84: '0,0,0',
+                    ellipse: 'GRS80',
+                    datumName: 'North_American_Datum_1983'
+                };
+                exports.nad27 = {
+                    nadgrids: '@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat',
+                    ellipse: 'clrk66',
+                    datumName: 'North_American_Datum_1927'
+                };
+                exports.potsdam = {
+                    towgs84: '606.0,23.0,413.0',
+                    ellipse: 'bessel',
+                    datumName: 'Potsdam Rauenberg 1950 DHDN'
+                };
+                exports.carthage = {
+                    towgs84: '-263.0,6.0,431.0',
+                    ellipse: 'clark80',
+                    datumName: 'Carthage 1934 Tunisia'
+                };
+                exports.hermannskogel = {
+                    towgs84: '653.0,-212.0,449.0',
+                    ellipse: 'bessel',
+                    datumName: 'Hermannskogel'
+                };
+                exports.ire65 = {
+                    towgs84: '482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15',
+                    ellipse: 'mod_airy',
+                    datumName: 'Ireland 1965'
+                };
+                exports.rassadiran = {
+                    towgs84: '-133.63,-157.5,-158.62',
+                    ellipse: 'intl',
+                    datumName: 'Rassadiran'
+                };
+                exports.nzgd49 = {
+                    towgs84: '59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993',
+                    ellipse: 'intl',
+                    datumName: 'New Zealand Geodetic Datum 1949'
+                };
+                exports.osgb36 = {
+                    towgs84: '446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894',
+                    ellipse: 'airy',
+                    datumName: 'Airy 1830'
+                };
+                exports.s_jtsk = {
+                    towgs84: '589,76,480',
+                    ellipse: 'bessel',
+                    datumName: 'S-JTSK (Ferro)'
+                };
+                exports.beduaram = {
+                    towgs84: '-106,-87,188',
+                    ellipse: 'clrk80',
+                    datumName: 'Beduaram'
+                };
+                exports.gunung_segara = {
+                    towgs84: '-403,684,41',
+                    ellipse: 'bessel',
+                    datumName: 'Gunung Segara Jakarta'
+                };
+                exports.rnb72 = {
+                    towgs84: '106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1',
+                    ellipse: 'intl',
+                    datumName: 'Reseau National Belge 1972'
+                };
+                return exports;
+            },
+            {}
+        ],
+        26: [
+            function (_dereq_, module, exports) {
+                exports.MERIT = {
+                    a: 6378137,
+                    rf: 298.257,
+                    ellipseName: 'MERIT 1983'
+                };
+                exports.SGS85 = {
+                    a: 6378136,
+                    rf: 298.257,
+                    ellipseName: 'Soviet Geodetic System 85'
+                };
+                exports.GRS80 = {
+                    a: 6378137,
+                    rf: 298.257222101,
+                    ellipseName: 'GRS 1980(IUGG, 1980)'
+                };
+                exports.IAU76 = {
+                    a: 6378140,
+                    rf: 298.257,
+                    ellipseName: 'IAU 1976'
+                };
+                exports.airy = {
+                    a: 6377563.396,
+                    b: 6356256.91,
+                    ellipseName: 'Airy 1830'
+                };
+                exports.APL4 = {
+                    a: 6378137,
+                    rf: 298.25,
+                    ellipseName: 'Appl. Physics. 1965'
+                };
+                exports.NWL9D = {
+                    a: 6378145,
+                    rf: 298.25,
+                    ellipseName: 'Naval Weapons Lab., 1965'
+                };
+                exports.mod_airy = {
+                    a: 6377340.189,
+                    b: 6356034.446,
+                    ellipseName: 'Modified Airy'
+                };
+                exports.andrae = {
+                    a: 6377104.43,
+                    rf: 300,
+                    ellipseName: 'Andrae 1876 (Den., Iclnd.)'
+                };
+                exports.aust_SA = {
+                    a: 6378160,
+                    rf: 298.25,
+                    ellipseName: 'Australian Natl & S. Amer. 1969'
+                };
+                exports.GRS67 = {
+                    a: 6378160,
+                    rf: 298.247167427,
+                    ellipseName: 'GRS 67(IUGG 1967)'
+                };
+                exports.bessel = {
+                    a: 6377397.155,
+                    rf: 299.1528128,
+                    ellipseName: 'Bessel 1841'
+                };
+                exports.bess_nam = {
+                    a: 6377483.865,
+                    rf: 299.1528128,
+                    ellipseName: 'Bessel 1841 (Namibia)'
+                };
+                exports.clrk66 = {
+                    a: 6378206.4,
+                    b: 6356583.8,
+                    ellipseName: 'Clarke 1866'
+                };
+                exports.clrk80 = {
+                    a: 6378249.145,
+                    rf: 293.4663,
+                    ellipseName: 'Clarke 1880 mod.'
+                };
+                exports.clrk58 = {
+                    a: 6378293.645208759,
+                    rf: 294.2606763692654,
+                    ellipseName: 'Clarke 1858'
+                };
+                exports.CPM = {
+                    a: 6375738.7,
+                    rf: 334.29,
+                    ellipseName: 'Comm. des Poids et Mesures 1799'
+                };
+                exports.delmbr = {
+                    a: 6376428,
+                    rf: 311.5,
+                    ellipseName: 'Delambre 1810 (Belgium)'
+                };
+                exports.engelis = {
+                    a: 6378136.05,
+                    rf: 298.2566,
+                    ellipseName: 'Engelis 1985'
+                };
+                exports.evrst30 = {
+                    a: 6377276.345,
+                    rf: 300.8017,
+                    ellipseName: 'Everest 1830'
+                };
+                exports.evrst48 = {
+                    a: 6377304.063,
+                    rf: 300.8017,
+                    ellipseName: 'Everest 1948'
+                };
+                exports.evrst56 = {
+                    a: 6377301.243,
+                    rf: 300.8017,
+                    ellipseName: 'Everest 1956'
+                };
+                exports.evrst69 = {
+                    a: 6377295.664,
+                    rf: 300.8017,
+                    ellipseName: 'Everest 1969'
+                };
+                exports.evrstSS = {
+                    a: 6377298.556,
+                    rf: 300.8017,
+                    ellipseName: 'Everest (Sabah & Sarawak)'
+                };
+                exports.fschr60 = {
+                    a: 6378166,
+                    rf: 298.3,
+                    ellipseName: 'Fischer (Mercury Datum) 1960'
+                };
+                exports.fschr60m = {
+                    a: 6378155,
+                    rf: 298.3,
+                    ellipseName: 'Fischer 1960'
+                };
+                exports.fschr68 = {
+                    a: 6378150,
+                    rf: 298.3,
+                    ellipseName: 'Fischer 1968'
+                };
+                exports.helmert = {
+                    a: 6378200,
+                    rf: 298.3,
+                    ellipseName: 'Helmert 1906'
+                };
+                exports.hough = {
+                    a: 6378270,
+                    rf: 297,
+                    ellipseName: 'Hough'
+                };
+                exports.intl = {
+                    a: 6378388,
+                    rf: 297,
+                    ellipseName: 'International 1909 (Hayford)'
+                };
+                exports.kaula = {
+                    a: 6378163,
+                    rf: 298.24,
+                    ellipseName: 'Kaula 1961'
+                };
+                exports.lerch = {
+                    a: 6378139,
+                    rf: 298.257,
+                    ellipseName: 'Lerch 1979'
+                };
+                exports.mprts = {
+                    a: 6397300,
+                    rf: 191,
+                    ellipseName: 'Maupertius 1738'
+                };
+                exports.new_intl = {
+                    a: 6378157.5,
+                    b: 6356772.2,
+                    ellipseName: 'New International 1967'
+                };
+                exports.plessis = {
+                    a: 6376523,
+                    rf: 6355863,
+                    ellipseName: 'Plessis 1817 (France)'
+                };
+                exports.krass = {
+                    a: 6378245,
+                    rf: 298.3,
+                    ellipseName: 'Krassovsky, 1942'
+                };
+                exports.SEasia = {
+                    a: 6378155,
+                    b: 6356773.3205,
+                    ellipseName: 'Southeast Asia'
+                };
+                exports.walbeck = {
+                    a: 6376896,
+                    b: 6355834.8467,
+                    ellipseName: 'Walbeck'
+                };
+                exports.WGS60 = {
+                    a: 6378165,
+                    rf: 298.3,
+                    ellipseName: 'WGS 60'
+                };
+                exports.WGS66 = {
+                    a: 6378145,
+                    rf: 298.25,
+                    ellipseName: 'WGS 66'
+                };
+                exports.WGS7 = {
+                    a: 6378135,
+                    rf: 298.26,
+                    ellipseName: 'WGS 72'
+                };
+                exports.WGS84 = {
+                    a: 6378137,
+                    rf: 298.257223563,
+                    ellipseName: 'WGS 84'
+                };
+                exports.sphere = {
+                    a: 6370997,
+                    b: 6370997,
+                    ellipseName: 'Normal Sphere (r=6370997)'
+                };
+                return exports;
+            },
+            {}
+        ],
+        27: [
+            function (_dereq_, module, exports) {
+                exports.greenwich = 0;
+                exports.lisbon = -9.131906111111;
+                exports.paris = 2.337229166667;
+                exports.bogota = -74.080916666667;
+                exports.madrid = -3.687938888889;
+                exports.rome = 12.452333333333;
+                exports.bern = 7.439583333333;
+                exports.jakarta = 106.807719444444;
+                exports.ferro = -17.666666666667;
+                exports.brussels = 4.367975;
+                exports.stockholm = 18.058277777778;
+                exports.athens = 23.7163375;
+                exports.oslo = 10.722916666667;
+                return exports;
+            },
+            {}
+        ],
+        28: [
+            function (_dereq_, module, exports) {
+                var proj = _dereq_('./Proj');
+                var transform = _dereq_('./transform');
+                var wgs84 = proj('WGS84');
+                function transformer(from, to, coords) {
+                    var transformedArray;
+                    if (Array.isArray(coords)) {
+                        transformedArray = transform(from, to, coords);
+                        if (coords.length === 3) {
+                            return [
+                                transformedArray.x,
+                                transformedArray.y,
+                                transformedArray.z
+                            ];
+                        } else {
+                            return [
+                                transformedArray.x,
+                                transformedArray.y
+                            ];
+                        }
+                    } else {
+                        return transform(from, to, coords);
+                    }
+                }
+                function checkProj(item) {
+                    if (item instanceof proj) {
+                        return item;
+                    }
+                    if (item.oProj) {
+                        return item.oProj;
+                    }
+                    return proj(item);
+                }
+                function proj4(fromProj, toProj, coord) {
+                    fromProj = checkProj(fromProj);
+                    var single = false;
+                    var obj;
+                    if (typeof toProj === 'undefined') {
+                        toProj = fromProj;
+                        fromProj = wgs84;
+                        single = true;
+                    } else if (typeof toProj.x !== 'undefined' || Array.isArray(toProj)) {
+                        coord = toProj;
+                        toProj = fromProj;
+                        fromProj = wgs84;
+                        single = true;
+                    }
+                    toProj = checkProj(toProj);
+                    if (coord) {
+                        return transformer(fromProj, toProj, coord);
+                    } else {
+                        obj = {
+                            forward: function (coords) {
+                                return transformer(fromProj, toProj, coords);
+                            },
+                            inverse: function (coords) {
+                                return transformer(toProj, fromProj, coords);
+                            }
+                        };
+                        if (single) {
+                            obj.oProj = toProj;
+                        }
+                        return obj;
+                    }
+                }
+                module.exports = proj4;
+                return exports;
+            },
+            {
+                './Proj': 2,
+                './transform': 64
+            }
+        ],
+        29: [
+            function (_dereq_, module, exports) {
+                var HALF_PI = Math.PI / 2;
+                var PJD_3PARAM = 1;
+                var PJD_7PARAM = 2;
+                var PJD_GRIDSHIFT = 3;
+                var PJD_WGS84 = 4;
+                var PJD_NODATUM = 5;
+                var SEC_TO_RAD = 0.00000484813681109536;
+                var AD_C = 1.0026;
+                var COS_67P5 = 0.3826834323650898;
+                var datum = function (proj) {
+                    if (!(this instanceof datum)) {
+                        return new datum(proj);
+                    }
+                    this.datum_type = PJD_WGS84;
+                    if (!proj) {
+                        return;
+                    }
+                    if (proj.datumCode && proj.datumCode === 'none') {
+                        this.datum_type = PJD_NODATUM;
+                    }
+                    if (proj.datum_params) {
+                        for (var i = 0; i < proj.datum_params.length; i++) {
+                            proj.datum_params[i] = parseFloat(proj.datum_params[i]);
+                        }
+                        if (proj.datum_params[0] !== 0 || proj.datum_params[1] !== 0 || proj.datum_params[2] !== 0) {
+                            this.datum_type = PJD_3PARAM;
+                        }
+                        if (proj.datum_params.length > 3) {
+                            if (proj.datum_params[3] !== 0 || proj.datum_params[4] !== 0 || proj.datum_params[5] !== 0 || proj.datum_params[6] !== 0) {
+                                this.datum_type = PJD_7PARAM;
+                                proj.datum_params[3] *= SEC_TO_RAD;
+                                proj.datum_params[4] *= SEC_TO_RAD;
+                                proj.datum_params[5] *= SEC_TO_RAD;
+                                proj.datum_params[6] = proj.datum_params[6] / 1000000 + 1;
+                            }
+                        }
+                    }
+                    this.datum_type = proj.grids ? PJD_GRIDSHIFT : this.datum_type;
+                    this.a = proj.a;
+                    this.b = proj.b;
+                    this.es = proj.es;
+                    this.ep2 = proj.ep2;
+                    this.datum_params = proj.datum_params;
+                    if (this.datum_type === PJD_GRIDSHIFT) {
+                        this.grids = proj.grids;
+                    }
+                };
+                datum.prototype = {
+                    compare_datums: function (dest) {
+                        if (this.datum_type !== dest.datum_type) {
+                            return false;
+                        } else if (this.a !== dest.a || Math.abs(this.es - dest.es) > 5e-11) {
+                            return false;
+                        } else if (this.datum_type === PJD_3PARAM) {
+                            return this.datum_params[0] === dest.datum_params[0] && this.datum_params[1] === dest.datum_params[1] && this.datum_params[2] === dest.datum_params[2];
+                        } else if (this.datum_type === PJD_7PARAM) {
+                            return this.datum_params[0] === dest.datum_params[0] && this.datum_params[1] === dest.datum_params[1] && this.datum_params[2] === dest.datum_params[2] && this.datum_params[3] === dest.datum_params[3] && this.datum_params[4] === dest.datum_params[4] && this.datum_params[5] === dest.datum_params[5] && this.datum_params[6] === dest.datum_params[6];
+                        } else if (this.datum_type === PJD_GRIDSHIFT || dest.datum_type === PJD_GRIDSHIFT) {
+                            return this.nadgrids === dest.nadgrids;
+                        } else {
+                            return true;
+                        }
+                    },
+                    geodetic_to_geocentric: function (p) {
+                        var Longitude = p.x;
+                        var Latitude = p.y;
+                        var Height = p.z ? p.z : 0;
+                        var X;
+                        var Y;
+                        var Z;
+                        var Error_Code = 0;
+                        var Rn;
+                        var Sin_Lat;
+                        var Sin2_Lat;
+                        var Cos_Lat;
+                        if (Latitude < -HALF_PI && Latitude > -1.001 * HALF_PI) {
+                            Latitude = -HALF_PI;
+                        } else if (Latitude > HALF_PI && Latitude < 1.001 * HALF_PI) {
+                            Latitude = HALF_PI;
+                        } else if (Latitude < -HALF_PI || Latitude > HALF_PI) {
+                            return null;
+                        }
+                        if (Longitude > Math.PI) {
+                            Longitude -= 2 * Math.PI;
+                        }
+                        Sin_Lat = Math.sin(Latitude);
+                        Cos_Lat = Math.cos(Latitude);
+                        Sin2_Lat = Sin_Lat * Sin_Lat;
+                        Rn = this.a / Math.sqrt(1 - this.es * Sin2_Lat);
+                        X = (Rn + Height) * Cos_Lat * Math.cos(Longitude);
+                        Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude);
+                        Z = (Rn * (1 - this.es) + Height) * Sin_Lat;
+                        p.x = X;
+                        p.y = Y;
+                        p.z = Z;
+                        return Error_Code;
+                    },
+                    geocentric_to_geodetic: function (p) {
+                        var genau = 1e-12;
+                        var genau2 = genau * genau;
+                        var maxiter = 30;
+                        var P;
+                        var RR;
+                        var CT;
+                        var ST;
+                        var RX;
+                        var RK;
+                        var RN;
+                        var CPHI0;
+                        var SPHI0;
+                        var CPHI;
+                        var SPHI;
+                        var SDPHI;
+                        var At_Pole;
+                        var iter;
+                        var X = p.x;
+                        var Y = p.y;
+                        var Z = p.z ? p.z : 0;
+                        var Longitude;
+                        var Latitude;
+                        var Height;
+                        At_Pole = false;
+                        P = Math.sqrt(X * X + Y * Y);
+                        RR = Math.sqrt(X * X + Y * Y + Z * Z);
+                        if (P / this.a < genau) {
+                            At_Pole = true;
+                            Longitude = 0;
+                            if (RR / this.a < genau) {
+                                Latitude = HALF_PI;
+                                Height = -this.b;
+                                return;
+                            }
+                        } else {
+                            Longitude = Math.atan2(Y, X);
+                        }
+                        CT = Z / RR;
+                        ST = P / RR;
+                        RX = 1 / Math.sqrt(1 - this.es * (2 - this.es) * ST * ST);
+                        CPHI0 = ST * (1 - this.es) * RX;
+                        SPHI0 = CT * RX;
+                        iter = 0;
+                        do {
+                            iter++;
+                            RN = this.a / Math.sqrt(1 - this.es * SPHI0 * SPHI0);
+                            Height = P * CPHI0 + Z * SPHI0 - RN * (1 - this.es * SPHI0 * SPHI0);
+                            RK = this.es * RN / (RN + Height);
+                            RX = 1 / Math.sqrt(1 - RK * (2 - RK) * ST * ST);
+                            CPHI = ST * (1 - RK) * RX;
+                            SPHI = CT * RX;
+                            SDPHI = SPHI * CPHI0 - CPHI * SPHI0;
+                            CPHI0 = CPHI;
+                            SPHI0 = SPHI;
+                        } while (SDPHI * SDPHI > genau2 && iter < maxiter);
+                        Latitude = Math.atan(SPHI / Math.abs(CPHI));
+                        p.x = Longitude;
+                        p.y = Latitude;
+                        p.z = Height;
+                        return p;
+                    },
+                    geocentric_to_geodetic_noniter: function (p) {
+                        var X = p.x;
+                        var Y = p.y;
+                        var Z = p.z ? p.z : 0;
+                        var Longitude;
+                        var Latitude;
+                        var Height;
+                        var W;
+                        var W2;
+                        var T0;
+                        var T1;
+                        var S0;
+                        var S1;
+                        var Sin_B0;
+                        var Sin3_B0;
+                        var Cos_B0;
+                        var Sin_p1;
+                        var Cos_p1;
+                        var Rn;
+                        var Sum;
+                        var At_Pole;
+                        X = parseFloat(X);
+                        Y = parseFloat(Y);
+                        Z = parseFloat(Z);
+                        At_Pole = false;
+                        if (X !== 0) {
+                            Longitude = Math.atan2(Y, X);
+                        } else {
+                            if (Y > 0) {
+                                Longitude = HALF_PI;
+                            } else if (Y < 0) {
+                                Longitude = -HALF_PI;
+                            } else {
+                                At_Pole = true;
+                                Longitude = 0;
+                                if (Z > 0) {
+                                    Latitude = HALF_PI;
+                                } else if (Z < 0) {
+                                    Latitude = -HALF_PI;
+                                } else {
+                                    Latitude = HALF_PI;
+                                    Height = -this.b;
+                                    return;
+                                }
+                            }
+                        }
+                        W2 = X * X + Y * Y;
+                        W = Math.sqrt(W2);
+                        T0 = Z * AD_C;
+                        S0 = Math.sqrt(T0 * T0 + W2);
+                        Sin_B0 = T0 / S0;
+                        Cos_B0 = W / S0;
+                        Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;
+                        T1 = Z + this.b * this.ep2 * Sin3_B0;
+                        Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0;
+                        S1 = Math.sqrt(T1 * T1 + Sum * Sum);
+                        Sin_p1 = T1 / S1;
+                        Cos_p1 = Sum / S1;
+                        Rn = this.a / Math.sqrt(1 - this.es * Sin_p1 * Sin_p1);
+                        if (Cos_p1 >= COS_67P5) {
+                            Height = W / Cos_p1 - Rn;
+                        } else if (Cos_p1 <= -COS_67P5) {
+                            Height = W / -Cos_p1 - Rn;
+                        } else {
+                            Height = Z / Sin_p1 + Rn * (this.es - 1);
+                        }
+                        if (At_Pole === false) {
+                            Latitude = Math.atan(Sin_p1 / Cos_p1);
+                        }
+                        p.x = Longitude;
+                        p.y = Latitude;
+                        p.z = Height;
+                        return p;
+                    },
+                    geocentric_to_wgs84: function (p) {
+                        if (this.datum_type === PJD_3PARAM) {
+                            p.x += this.datum_params[0];
+                            p.y += this.datum_params[1];
+                            p.z += this.datum_params[2];
+                        } else if (this.datum_type === PJD_7PARAM) {
+                            var Dx_BF = this.datum_params[0];
+                            var Dy_BF = this.datum_params[1];
+                            var Dz_BF = this.datum_params[2];
+                            var Rx_BF = this.datum_params[3];
+                            var Ry_BF = this.datum_params[4];
+                            var Rz_BF = this.datum_params[5];
+                            var M_BF = this.datum_params[6];
+                            var x_out = M_BF * (p.x - Rz_BF * p.y + Ry_BF * p.z) + Dx_BF;
+                            var y_out = M_BF * (Rz_BF * p.x + p.y - Rx_BF * p.z) + Dy_BF;
+                            var z_out = M_BF * (-Ry_BF * p.x + Rx_BF * p.y + p.z) + Dz_BF;
+                            p.x = x_out;
+                            p.y = y_out;
+                            p.z = z_out;
+                        }
+                    },
+                    geocentric_from_wgs84: function (p) {
+                        if (this.datum_type === PJD_3PARAM) {
+                            p.x -= this.datum_params[0];
+                            p.y -= this.datum_params[1];
+                            p.z -= this.datum_params[2];
+                        } else if (this.datum_type === PJD_7PARAM) {
+                            var Dx_BF = this.datum_params[0];
+                            var Dy_BF = this.datum_params[1];
+                            var Dz_BF = this.datum_params[2];
+                            var Rx_BF = this.datum_params[3];
+                            var Ry_BF = this.datum_params[4];
+                            var Rz_BF = this.datum_params[5];
+                            var M_BF = this.datum_params[6];
+                            var x_tmp = (p.x - Dx_BF) / M_BF;
+                            var y_tmp = (p.y - Dy_BF) / M_BF;
+                            var z_tmp = (p.z - Dz_BF) / M_BF;
+                            p.x = x_tmp + Rz_BF * y_tmp - Ry_BF * z_tmp;
+                            p.y = -Rz_BF * x_tmp + y_tmp + Rx_BF * z_tmp;
+                            p.z = Ry_BF * x_tmp - Rx_BF * y_tmp + z_tmp;
+                        }
+                    }
+                };
+                module.exports = datum;
+                return exports;
+            },
+            {}
+        ],
+        30: [
+            function (_dereq_, module, exports) {
+                var PJD_3PARAM = 1;
+                var PJD_7PARAM = 2;
+                var PJD_GRIDSHIFT = 3;
+                var PJD_NODATUM = 5;
+                var SRS_WGS84_SEMIMAJOR = 6378137;
+                var SRS_WGS84_ESQUARED = 0.006694379990141316;
+                module.exports = function (source, dest, point) {
+                    var wp, i, l;
+                    function checkParams(fallback) {
+                        return fallback === PJD_3PARAM || fallback === PJD_7PARAM;
+                    }
+                    if (source.compare_datums(dest)) {
+                        return point;
+                    }
+                    if (source.datum_type === PJD_NODATUM || dest.datum_type === PJD_NODATUM) {
+                        return point;
+                    }
+                    var src_a = source.a;
+                    var src_es = source.es;
+                    var dst_a = dest.a;
+                    var dst_es = dest.es;
+                    var fallback = source.datum_type;
+                    if (fallback === PJD_GRIDSHIFT) {
+                        if (this.apply_gridshift(source, 0, point) === 0) {
+                            source.a = SRS_WGS84_SEMIMAJOR;
+                            source.es = SRS_WGS84_ESQUARED;
+                        } else {
+                            if (!source.datum_params) {
+                                source.a = src_a;
+                                source.es = source.es;
+                                return point;
+                            }
+                            wp = 1;
+                            for (i = 0, l = source.datum_params.length; i < l; i++) {
+                                wp *= source.datum_params[i];
+                            }
+                            if (wp === 0) {
+                                source.a = src_a;
+                                source.es = source.es;
+                                return point;
+                            }
+                            if (source.datum_params.length > 3) {
+                                fallback = PJD_7PARAM;
+                            } else {
+                                fallback = PJD_3PARAM;
+                            }
+                        }
+                    }
+                    if (dest.datum_type === PJD_GRIDSHIFT) {
+                        dest.a = SRS_WGS84_SEMIMAJOR;
+                        dest.es = SRS_WGS84_ESQUARED;
+                    }
+                    if (source.es !== dest.es || source.a !== dest.a || checkParams(fallback) || checkParams(dest.datum_type)) {
+                        source.geodetic_to_geocentric(point);
+                        if (checkParams(source.datum_type)) {
+                            source.geocentric_to_wgs84(point);
+                        }
+                        if (checkParams(dest.datum_type)) {
+                            dest.geocentric_from_wgs84(point);
+                        }
+                        dest.geocentric_to_geodetic(point);
+                    }
+                    if (dest.datum_type === PJD_GRIDSHIFT) {
+                        this.apply_gridshift(dest, 1, point);
+                    }
+                    source.a = src_a;
+                    source.es = src_es;
+                    dest.a = dst_a;
+                    dest.es = dst_es;
+                    return point;
+                };
+                return exports;
+            },
+            {}
+        ],
+        31: [
+            function (_dereq_, module, exports) {
+                var globals = _dereq_('./global');
+                var parseProj = _dereq_('./projString');
+                var wkt = _dereq_('./wkt');
+                function defs(name) {
+                    var that = this;
+                    if (arguments.length === 2) {
+                        var def = arguments[1];
+                        if (typeof def === 'string') {
+                            if (def[0] === '+') {
+                                defs[name] = parseProj(arguments[1]);
+                            } else {
+                                defs[name] = wkt(arguments[1]);
+                            }
+                        } else {
+                            defs[name] = def;
+                        }
+                    } else if (arguments.length === 1) {
+                        if (Array.isArray(name)) {
+                            return name.map(function (v) {
+                                if (Array.isArray(v)) {
+                                    defs.apply(that, v);
+                                } else {
+                                    defs(v);
+                                }
+                            });
+                        } else if (typeof name === 'string') {
+                            if (name in defs) {
+                                return defs[name];
+                            }
+                        } else if ('EPSG' in name) {
+                            defs['EPSG:' + name.EPSG] = name;
+                        } else if ('ESRI' in name) {
+                            defs['ESRI:' + name.ESRI] = name;
+                        } else if ('IAU2000' in name) {
+                            defs['IAU2000:' + name.IAU2000] = name;
+                        } else {
+                            console.log(name);
+                        }
+                        return;
+                    }
+                }
+                globals(defs);
+                module.exports = defs;
+                return exports;
+            },
+            {
+                './global': 34,
+                './projString': 37,
+                './wkt': 65
+            }
+        ],
+        32: [
+            function (_dereq_, module, exports) {
+                var Datum = _dereq_('./constants/Datum');
+                var Ellipsoid = _dereq_('./constants/Ellipsoid');
+                var extend = _dereq_('./extend');
+                var datum = _dereq_('./datum');
+                var EPSLN = 1e-10;
+                var SIXTH = 0.16666666666666666;
+                var RA4 = 0.04722222222222222;
+                var RA6 = 0.022156084656084655;
+                module.exports = function (json) {
+                    if (json.datumCode && json.datumCode !== 'none') {
+                        var datumDef = Datum[json.datumCode];
+                        if (datumDef) {
+                            json.datum_params = datumDef.towgs84 ? datumDef.towgs84.split(',') : null;
+                            json.ellps = datumDef.ellipse;
+                            json.datumName = datumDef.datumName ? datumDef.datumName : json.datumCode;
+                        }
+                    }
+                    if (!json.a) {
+                        var ellipse = Ellipsoid[json.ellps] ? Ellipsoid[json.ellps] : Ellipsoid.WGS84;
+                        extend(json, ellipse);
+                    }
+                    if (json.rf && !json.b) {
+                        json.b = (1 - 1 / json.rf) * json.a;
+                    }
+                    if (json.rf === 0 || Math.abs(json.a - json.b) < EPSLN) {
+                        json.sphere = true;
+                        json.b = json.a;
+                    }
+                    json.a2 = json.a * json.a;
+                    json.b2 = json.b * json.b;
+                    json.es = (json.a2 - json.b2) / json.a2;
+                    json.e = Math.sqrt(json.es);
+                    if (json.R_A) {
+                        json.a *= 1 - json.es * (SIXTH + json.es * (RA4 + json.es * RA6));
+                        json.a2 = json.a * json.a;
+                        json.b2 = json.b * json.b;
+                        json.es = 0;
+                    }
+                    json.ep2 = (json.a2 - json.b2) / json.b2;
+                    if (!json.k0) {
+                        json.k0 = 1;
+                    }
+                    if (!json.axis) {
+                        json.axis = 'enu';
+                    }
+                    json.datum = datum(json);
+                    return json;
+                };
+                return exports;
+            },
+            {
+                './constants/Datum': 25,
+                './constants/Ellipsoid': 26,
+                './datum': 29,
+                './extend': 33
+            }
+        ],
+        33: [
+            function (_dereq_, module, exports) {
+                module.exports = function (destination, source) {
+                    destination = destination || {};
+                    var value, property;
+                    if (!source) {
+                        return destination;
+                    }
+                    for (property in source) {
+                        value = source[property];
+                        if (value !== undefined) {
+                            destination[property] = value;
+                        }
+                    }
+                    return destination;
+                };
+                return exports;
+            },
+            {}
+        ],
+        34: [
+            function (_dereq_, module, exports) {
+                module.exports = function (defs) {
+                    defs('EPSG:4326', '+title=WGS 84 (long/lat) +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees');
+                    defs('EPSG:4269', '+title=NAD83 (long/lat) +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees');
+                    defs('EPSG:3857', '+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs');
+                    defs.WGS84 = defs['EPSG:4326'];
+                    defs['EPSG:3785'] = defs['EPSG:3857'];
+                    defs.GOOGLE = defs['EPSG:3857'];
+                    defs['EPSG:900913'] = defs['EPSG:3857'];
+                    defs['EPSG:102113'] = defs['EPSG:3857'];
+                };
+                return exports;
+            },
+            {}
+        ],
+        35: [
+            function (_dereq_, module, exports) {
+                var proj4 = _dereq_('./core');
+                proj4.defaultDatum = 'WGS84';
+                proj4.Proj = _dereq_('./Proj');
+                proj4.WGS84 = new proj4.Proj('WGS84');
+                proj4.Point = _dereq_('./Point');
+                proj4.toPoint = _dereq_('./common/toPoint');
+                proj4.defs = _dereq_('./defs');
+                proj4.transform = _dereq_('./transform');
+                proj4.mgrs = _dereq_('mgrs');
+                proj4.version = _dereq_('../package.json').version;
+                _dereq_('./includedProjections')(proj4);
+                module.exports = proj4;
+                return exports;
+            },
+            {
+                '../package.json': 67,
+                './Point': 1,
+                './Proj': 2,
+                './common/toPoint': 23,
+                './core': 28,
+                './defs': 31,
+                './includedProjections': 'gWUPNW',
+                './transform': 64,
+                'mgrs': 66
+            }
+        ],
+        36: [
+            function (_dereq_, module, exports) {
+                var defs = _dereq_('./defs');
+                var wkt = _dereq_('./wkt');
+                var projStr = _dereq_('./projString');
+                function testObj(code) {
+                    return typeof code === 'string';
+                }
+                function testDef(code) {
+                    return code in defs;
+                }
+                function testWKT(code) {
+                    var codeWords = [
+                        'GEOGCS',
+                        'GEOCCS',
+                        'PROJCS',
+                        'LOCAL_CS'
+                    ];
+                    return codeWords.reduce(function (a, b) {
+                        return a + 1 + code.indexOf(b);
+                    }, 0);
+                }
+                function testProj(code) {
+                    return code[0] === '+';
+                }
+                function parse(code) {
+                    if (testObj(code)) {
+                        if (testDef(code)) {
+                            return defs[code];
+                        } else if (testWKT(code)) {
+                            return wkt(code);
+                        } else if (testProj(code)) {
+                            return projStr(code);
+                        }
+                    } else {
+                        return code;
+                    }
+                }
+                module.exports = parse;
+                return exports;
+            },
+            {
+                './defs': 31,
+                './projString': 37,
+                './wkt': 65
+            }
+        ],
+        37: [
+            function (_dereq_, module, exports) {
+                var D2R = 0.017453292519943295;
+                var PrimeMeridian = _dereq_('./constants/PrimeMeridian');
+                module.exports = function (defData) {
+                    var self = {};
+                    var paramObj = {};
+                    defData.split('+').map(function (v) {
+                        return v.trim();
+                    }).filter(function (a) {
+                        return a;
+                    }).forEach(function (a) {
+                        var split = a.split('=');
+                        split.push(true);
+                        paramObj[split[0].toLowerCase()] = split[1];
+                    });
+                    var paramName, paramVal, paramOutname;
+                    var params = {
+                        proj: 'projName',
+                        datum: 'datumCode',
+                        rf: function (v) {
+                            self.rf = parseFloat(v, 10);
+                        },
+                        lat_0: function (v) {
+                            self.lat0 = v * D2R;
+                        },
+                        lat_1: function (v) {
+                            self.lat1 = v * D2R;
+                        },
+                        lat_2: function (v) {
+                            self.lat2 = v * D2R;
+                        },
+                        lat_ts: function (v) {
+                            self.lat_ts = v * D2R;
+                        },
+                        lon_0: function (v) {
+                            self.long0 = v * D2R;
+                        },
+                        lon_1: function (v) {
+                            self.long1 = v * D2R;
+                        },
+                        lon_2: function (v) {
+                            self.long2 = v * D2R;
+                        },
+                        alpha: function (v) {
+                            self.alpha = parseFloat(v) * D2R;
+                        },
+                        lonc: function (v) {
+                            self.longc = v * D2R;
+                        },
+                        x_0: function (v) {
+                            self.x0 = parseFloat(v, 10);
+                        },
+                        y_0: function (v) {
+                            self.y0 = parseFloat(v, 10);
+                        },
+                        k_0: function (v) {
+                            self.k0 = parseFloat(v, 10);
+                        },
+                        k: function (v) {
+                            self.k0 = parseFloat(v, 10);
+                        },
+                        r_a: function () {
+                            self.R_A = true;
+                        },
+                        zone: function (v) {
+                            self.zone = parseInt(v, 10);
+                        },
+                        south: function () {
+                            self.utmSouth = true;
+                        },
+                        towgs84: function (v) {
+                            self.datum_params = v.split(',').map(function (a) {
+                                return parseFloat(a, 10);
+                            });
+                        },
+                        to_meter: function (v) {
+                            self.to_meter = parseFloat(v, 10);
+                        },
+                        from_greenwich: function (v) {
+                            self.from_greenwich = v * D2R;
+                        },
+                        pm: function (v) {
+                            self.from_greenwich = (PrimeMeridian[v] ? PrimeMeridian[v] : parseFloat(v, 10)) * D2R;
+                        },
+                        nadgrids: function (v) {
+                            if (v === '@null') {
+                                self.datumCode = 'none';
+                            } else {
+                                self.nadgrids = v;
+                            }
+                        },
+                        axis: function (v) {
+                            var legalAxis = 'ewnsud';
+                            if (v.length === 3 && legalAxis.indexOf(v.substr(0, 1)) !== -1 && legalAxis.indexOf(v.substr(1, 1)) !== -1 && legalAxis.indexOf(v.substr(2, 1)) !== -1) {
+                                self.axis = v;
+                            }
+                        }
+                    };
+                    for (paramName in paramObj) {
+                        paramVal = paramObj[paramName];
+                        if (paramName in params) {
+                            paramOutname = params[paramName];
+                            if (typeof paramOutname === 'function') {
+                                paramOutname(paramVal);
+                            } else {
+                                self[paramOutname] = paramVal;
+                            }
+                        } else {
+                            self[paramName] = paramVal;
+                        }
+                    }
+                    if (typeof self.datumCode === 'string' && self.datumCode !== 'WGS84') {
+                        self.datumCode = self.datumCode.toLowerCase();
+                    }
+                    return self;
+                };
+                return exports;
+            },
+            { './constants/PrimeMeridian': 27 }
+        ],
+        38: [
+            function (_dereq_, module, exports) {
+                var projs = [
+                    _dereq_('./projections/merc'),
+                    _dereq_('./projections/longlat')
+                ];
+                var names = {};
+                var projStore = [];
+                function add(proj, i) {
+                    var len = projStore.length;
+                    if (!proj.names) {
+                        console.log(i);
+                        return true;
+                    }
+                    projStore[len] = proj;
+                    proj.names.forEach(function (n) {
+                        names[n.toLowerCase()] = len;
+                    });
+                    return this;
+                }
+                exports.add = add;
+                exports.get = function (name) {
+                    if (!name) {
+                        return false;
+                    }
+                    var n = name.toLowerCase();
+                    if (typeof names[n] !== 'undefined' && projStore[names[n]]) {
+                        return projStore[names[n]];
+                    }
+                };
+                exports.start = function () {
+                    projs.forEach(add);
+                };
+                return exports;
+            },
+            {
+                './projections/longlat': 50,
+                './projections/merc': 51
+            }
+        ],
+        39: [
+            function (_dereq_, module, exports) {
+                var EPSLN = 1e-10;
+                var msfnz = _dereq_('../common/msfnz');
+                var qsfnz = _dereq_('../common/qsfnz');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var asinz = _dereq_('../common/asinz');
+                exports.init = function () {
+                    if (Math.abs(this.lat1 + this.lat2) < EPSLN) {
+                        return;
+                    }
+                    this.temp = this.b / this.a;
+                    this.es = 1 - Math.pow(this.temp, 2);
+                    this.e3 = Math.sqrt(this.es);
+                    this.sin_po = Math.sin(this.lat1);
+                    this.cos_po = Math.cos(this.lat1);
+                    this.t1 = this.sin_po;
+                    this.con = this.sin_po;
+                    this.ms1 = msfnz(this.e3, this.sin_po, this.cos_po);
+                    this.qs1 = qsfnz(this.e3, this.sin_po, this.cos_po);
+                    this.sin_po = Math.sin(this.lat2);
+                    this.cos_po = Math.cos(this.lat2);
+                    this.t2 = this.sin_po;
+                    this.ms2 = msfnz(this.e3, this.sin_po, this.cos_po);
+                    this.qs2 = qsfnz(this.e3, this.sin_po, this.cos_po);
+                    this.sin_po = Math.sin(this.lat0);
+                    this.cos_po = Math.cos(this.lat0);
+                    this.t3 = this.sin_po;
+                    this.qs0 = qsfnz(this.e3, this.sin_po, this.cos_po);
+                    if (Math.abs(this.lat1 - this.lat2) > EPSLN) {
+                        this.ns0 = (this.ms1 * this.ms1 - this.ms2 * this.ms2) / (this.qs2 - this.qs1);
+                    } else {
+                        this.ns0 = this.con;
+                    }
+                    this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1;
+                    this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0) / this.ns0;
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    this.sin_phi = Math.sin(lat);
+                    this.cos_phi = Math.cos(lat);
+                    var qs = qsfnz(this.e3, this.sin_phi, this.cos_phi);
+                    var rh1 = this.a * Math.sqrt(this.c - this.ns0 * qs) / this.ns0;
+                    var theta = this.ns0 * adjust_lon(lon - this.long0);
+                    var x = rh1 * Math.sin(theta) + this.x0;
+                    var y = this.rh - rh1 * Math.cos(theta) + this.y0;
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var rh1, qs, con, theta, lon, lat;
+                    p.x -= this.x0;
+                    p.y = this.rh - p.y + this.y0;
+                    if (this.ns0 >= 0) {
+                        rh1 = Math.sqrt(p.x * p.x + p.y * p.y);
+                        con = 1;
+                    } else {
+                        rh1 = -Math.sqrt(p.x * p.x + p.y * p.y);
+                        con = -1;
+                    }
+                    theta = 0;
+                    if (rh1 !== 0) {
+                        theta = Math.atan2(con * p.x, con * p.y);
+                    }
+                    con = rh1 * this.ns0 / this.a;
+                    if (this.sphere) {
+                        lat = Math.asin((this.c - con * con) / (2 * this.ns0));
+                    } else {
+                        qs = (this.c - con * con) / this.ns0;
+                        lat = this.phi1z(this.e3, qs);
+                    }
+                    lon = adjust_lon(theta / this.ns0 + this.long0);
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.phi1z = function (eccent, qs) {
+                    var sinphi, cosphi, con, com, dphi;
+                    var phi = asinz(0.5 * qs);
+                    if (eccent < EPSLN) {
+                        return phi;
+                    }
+                    var eccnts = eccent * eccent;
+                    for (var i = 1; i <= 25; i++) {
+                        sinphi = Math.sin(phi);
+                        cosphi = Math.cos(phi);
+                        con = eccent * sinphi;
+                        com = 1 - con * con;
+                        dphi = 0.5 * com * com / cosphi * (qs / (1 - eccnts) - sinphi / com + 0.5 / eccent * Math.log((1 - con) / (1 + con)));
+                        phi = phi + dphi;
+                        if (Math.abs(dphi) <= 1e-7) {
+                            return phi;
+                        }
+                    }
+                    return null;
+                };
+                exports.names = [
+                    'Albers_Conic_Equal_Area',
+                    'Albers',
+                    'aea'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/asinz': 6,
+                '../common/msfnz': 15,
+                '../common/qsfnz': 20
+            }
+        ],
+        40: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var HALF_PI = Math.PI / 2;
+                var EPSLN = 1e-10;
+                var mlfn = _dereq_('../common/mlfn');
+                var e0fn = _dereq_('../common/e0fn');
+                var e1fn = _dereq_('../common/e1fn');
+                var e2fn = _dereq_('../common/e2fn');
+                var e3fn = _dereq_('../common/e3fn');
+                var gN = _dereq_('../common/gN');
+                var asinz = _dereq_('../common/asinz');
+                var imlfn = _dereq_('../common/imlfn');
+                exports.init = function () {
+                    this.sin_p12 = Math.sin(this.lat0);
+                    this.cos_p12 = Math.cos(this.lat0);
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var sinphi = Math.sin(p.y);
+                    var cosphi = Math.cos(p.y);
+                    var dlon = adjust_lon(lon - this.long0);
+                    var e0, e1, e2, e3, Mlp, Ml, tanphi, Nl1, Nl, psi, Az, G, H, GH, Hs, c, kp, cos_c, s, s2, s3, s4, s5;
+                    if (this.sphere) {
+                        if (Math.abs(this.sin_p12 - 1) <= EPSLN) {
+                            p.x = this.x0 + this.a * (HALF_PI - lat) * Math.sin(dlon);
+                            p.y = this.y0 - this.a * (HALF_PI - lat) * Math.cos(dlon);
+                            return p;
+                        } else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {
+                            p.x = this.x0 + this.a * (HALF_PI + lat) * Math.sin(dlon);
+                            p.y = this.y0 + this.a * (HALF_PI + lat) * Math.cos(dlon);
+                            return p;
+                        } else {
+                            cos_c = this.sin_p12 * sinphi + this.cos_p12 * cosphi * Math.cos(dlon);
+                            c = Math.acos(cos_c);
+                            kp = c / Math.sin(c);
+                            p.x = this.x0 + this.a * kp * cosphi * Math.sin(dlon);
+                            p.y = this.y0 + this.a * kp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * Math.cos(dlon));
+                            return p;
+                        }
+                    } else {
+                        e0 = e0fn(this.es);
+                        e1 = e1fn(this.es);
+                        e2 = e2fn(this.es);
+                        e3 = e3fn(this.es);
+                        if (Math.abs(this.sin_p12 - 1) <= EPSLN) {
+                            Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
+                            Ml = this.a * mlfn(e0, e1, e2, e3, lat);
+                            p.x = this.x0 + (Mlp - Ml) * Math.sin(dlon);
+                            p.y = this.y0 - (Mlp - Ml) * Math.cos(dlon);
+                            return p;
+                        } else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {
+                            Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
+                            Ml = this.a * mlfn(e0, e1, e2, e3, lat);
+                            p.x = this.x0 + (Mlp + Ml) * Math.sin(dlon);
+                            p.y = this.y0 + (Mlp + Ml) * Math.cos(dlon);
+                            return p;
+                        } else {
+                            tanphi = sinphi / cosphi;
+                            Nl1 = gN(this.a, this.e, this.sin_p12);
+                            Nl = gN(this.a, this.e, sinphi);
+                            psi = Math.atan((1 - this.es) * tanphi + this.es * Nl1 * this.sin_p12 / (Nl * cosphi));
+                            Az = Math.atan2(Math.sin(dlon), this.cos_p12 * Math.tan(psi) - this.sin_p12 * Math.cos(dlon));
+                            if (Az === 0) {
+                                s = Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi));
+                            } else if (Math.abs(Math.abs(Az) - Math.PI) <= EPSLN) {
+                                s = -Math.asin(this.cos_p12 * Math.sin(psi) - this.sin_p12 * Math.cos(psi));
+                            } else {
+                                s = Math.asin(Math.sin(dlon) * Math.cos(psi) / Math.sin(Az));
+                            }
+                            G = this.e * this.sin_p12 / Math.sqrt(1 - this.es);
+                            H = this.e * this.cos_p12 * Math.cos(Az) / Math.sqrt(1 - this.es);
+                            GH = G * H;
+                            Hs = H * H;
+                            s2 = s * s;
+                            s3 = s2 * s;
+                            s4 = s3 * s;
+                            s5 = s4 * s;
+                            c = Nl1 * s * (1 - s2 * Hs * (1 - Hs) / 6 + s3 / 8 * GH * (1 - 2 * Hs) + s4 / 120 * (Hs * (4 - 7 * Hs) - 3 * G * G * (1 - 7 * Hs)) - s5 / 48 * GH);
+                            p.x = this.x0 + c * Math.sin(Az);
+                            p.y = this.y0 + c * Math.cos(Az);
+                            return p;
+                        }
+                    }
+                };
+                exports.inverse = function (p) {
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    var rh, z, sinz, cosz, lon, lat, con, e0, e1, e2, e3, Mlp, M, N1, psi, Az, cosAz, tmp, A, B, D, Ee, F;
+                    if (this.sphere) {
+                        rh = Math.sqrt(p.x * p.x + p.y * p.y);
+                        if (rh > 2 * HALF_PI * this.a) {
+                            return;
+                        }
+                        z = rh / this.a;
+                        sinz = Math.sin(z);
+                        cosz = Math.cos(z);
+                        lon = this.long0;
+                        if (Math.abs(rh) <= EPSLN) {
+                            lat = this.lat0;
+                        } else {
+                            lat = asinz(cosz * this.sin_p12 + p.y * sinz * this.cos_p12 / rh);
+                            con = Math.abs(this.lat0) - HALF_PI;
+                            if (Math.abs(con) <= EPSLN) {
+                                if (this.lat0 >= 0) {
+                                    lon = adjust_lon(this.long0 + Math.atan2(p.x, -p.y));
+                                } else {
+                                    lon = adjust_lon(this.long0 - Math.atan2(-p.x, p.y));
+                                }
+                            } else {
+                                lon = adjust_lon(this.long0 + Math.atan2(p.x * sinz, rh * this.cos_p12 * cosz - p.y * this.sin_p12 * sinz));
+                            }
+                        }
+                        p.x = lon;
+                        p.y = lat;
+                        return p;
+                    } else {
+                        e0 = e0fn(this.es);
+                        e1 = e1fn(this.es);
+                        e2 = e2fn(this.es);
+                        e3 = e3fn(this.es);
+                        if (Math.abs(this.sin_p12 - 1) <= EPSLN) {
+                            Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
+                            rh = Math.sqrt(p.x * p.x + p.y * p.y);
+                            M = Mlp - rh;
+                            lat = imlfn(M / this.a, e0, e1, e2, e3);
+                            lon = adjust_lon(this.long0 + Math.atan2(p.x, -1 * p.y));
+                            p.x = lon;
+                            p.y = lat;
+                            return p;
+                        } else if (Math.abs(this.sin_p12 + 1) <= EPSLN) {
+                            Mlp = this.a * mlfn(e0, e1, e2, e3, HALF_PI);
+                            rh = Math.sqrt(p.x * p.x + p.y * p.y);
+                            M = rh - Mlp;
+                            lat = imlfn(M / this.a, e0, e1, e2, e3);
+                            lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));
+                            p.x = lon;
+                            p.y = lat;
+                            return p;
+                        } else {
+                            rh = Math.sqrt(p.x * p.x + p.y * p.y);
+                            Az = Math.atan2(p.x, p.y);
+                            N1 = gN(this.a, this.e, this.sin_p12);
+                            cosAz = Math.cos(Az);
+                            tmp = this.e * this.cos_p12 * cosAz;
+                            A = -tmp * tmp / (1 - this.es);
+                            B = 3 * this.es * (1 - A) * this.sin_p12 * this.cos_p12 * cosAz / (1 - this.es);
+                            D = rh / N1;
+                            Ee = D - A * (1 + A) * Math.pow(D, 3) / 6 - B * (1 + 3 * A) * Math.pow(D, 4) / 24;
+                            F = 1 - A * Ee * Ee / 2 - D * Ee * Ee * Ee / 6;
+                            psi = Math.asin(this.sin_p12 * Math.cos(Ee) + this.cos_p12 * Math.sin(Ee) * cosAz);
+                            lon = adjust_lon(this.long0 + Math.asin(Math.sin(Az) * Math.sin(Ee) / Math.cos(psi)));
+                            lat = Math.atan((1 - this.es * F * this.sin_p12 / Math.sin(psi)) * Math.tan(psi) / (1 - this.es));
+                            p.x = lon;
+                            p.y = lat;
+                            return p;
+                        }
+                    }
+                };
+                exports.names = [
+                    'Azimuthal_Equidistant',
+                    'aeqd'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/asinz': 6,
+                '../common/e0fn': 7,
+                '../common/e1fn': 8,
+                '../common/e2fn': 9,
+                '../common/e3fn': 10,
+                '../common/gN': 11,
+                '../common/imlfn': 12,
+                '../common/mlfn': 14
+            }
+        ],
+        41: [
+            function (_dereq_, module, exports) {
+                var mlfn = _dereq_('../common/mlfn');
+                var e0fn = _dereq_('../common/e0fn');
+                var e1fn = _dereq_('../common/e1fn');
+                var e2fn = _dereq_('../common/e2fn');
+                var e3fn = _dereq_('../common/e3fn');
+                var gN = _dereq_('../common/gN');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var adjust_lat = _dereq_('../common/adjust_lat');
+                var imlfn = _dereq_('../common/imlfn');
+                var HALF_PI = Math.PI / 2;
+                var EPSLN = 1e-10;
+                exports.init = function () {
+                    if (!this.sphere) {
+                        this.e0 = e0fn(this.es);
+                        this.e1 = e1fn(this.es);
+                        this.e2 = e2fn(this.es);
+                        this.e3 = e3fn(this.es);
+                        this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
+                    }
+                };
+                exports.forward = function (p) {
+                    var x, y;
+                    var lam = p.x;
+                    var phi = p.y;
+                    lam = adjust_lon(lam - this.long0);
+                    if (this.sphere) {
+                        x = this.a * Math.asin(Math.cos(phi) * Math.sin(lam));
+                        y = this.a * (Math.atan2(Math.tan(phi), Math.cos(lam)) - this.lat0);
+                    } else {
+                        var sinphi = Math.sin(phi);
+                        var cosphi = Math.cos(phi);
+                        var nl = gN(this.a, this.e, sinphi);
+                        var tl = Math.tan(phi) * Math.tan(phi);
+                        var al = lam * Math.cos(phi);
+                        var asq = al * al;
+                        var cl = this.es * cosphi * cosphi / (1 - this.es);
+                        var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi);
+                        x = nl * al * (1 - asq * tl * (1 / 6 - (8 - tl + 8 * cl) * asq / 120));
+                        y = ml - this.ml0 + nl * sinphi / cosphi * asq * (0.5 + (5 - tl + 6 * cl) * asq / 24);
+                    }
+                    p.x = x + this.x0;
+                    p.y = y + this.y0;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    var x = p.x / this.a;
+                    var y = p.y / this.a;
+                    var phi, lam;
+                    if (this.sphere) {
+                        var dd = y + this.lat0;
+                        phi = Math.asin(Math.sin(dd) * Math.cos(x));
+                        lam = Math.atan2(Math.tan(x), Math.cos(dd));
+                    } else {
+                        var ml1 = this.ml0 / this.a + y;
+                        var phi1 = imlfn(ml1, this.e0, this.e1, this.e2, this.e3);
+                        if (Math.abs(Math.abs(phi1) - HALF_PI) <= EPSLN) {
+                            p.x = this.long0;
+                            p.y = HALF_PI;
+                            if (y < 0) {
+                                p.y *= -1;
+                            }
+                            return p;
+                        }
+                        var nl1 = gN(this.a, this.e, Math.sin(phi1));
+                        var rl1 = nl1 * nl1 * nl1 / this.a / this.a * (1 - this.es);
+                        var tl1 = Math.pow(Math.tan(phi1), 2);
+                        var dl = x * this.a / nl1;
+                        var dsq = dl * dl;
+                        phi = phi1 - nl1 * Math.tan(phi1) / rl1 * dl * dl * (0.5 - (1 + 3 * tl1) * dl * dl / 24);
+                        lam = dl * (1 - dsq * (tl1 / 3 + (1 + 3 * tl1) * tl1 * dsq / 15)) / Math.cos(phi1);
+                    }
+                    p.x = adjust_lon(lam + this.long0);
+                    p.y = adjust_lat(phi);
+                    return p;
+                };
+                exports.names = [
+                    'Cassini',
+                    'Cassini_Soldner',
+                    'cass'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lat': 4,
+                '../common/adjust_lon': 5,
+                '../common/e0fn': 7,
+                '../common/e1fn': 8,
+                '../common/e2fn': 9,
+                '../common/e3fn': 10,
+                '../common/gN': 11,
+                '../common/imlfn': 12,
+                '../common/mlfn': 14
+            }
+        ],
+        42: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var qsfnz = _dereq_('../common/qsfnz');
+                var msfnz = _dereq_('../common/msfnz');
+                var iqsfnz = _dereq_('../common/iqsfnz');
+                exports.init = function () {
+                    if (!this.sphere) {
+                        this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
+                    }
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var x, y;
+                    var dlon = adjust_lon(lon - this.long0);
+                    if (this.sphere) {
+                        x = this.x0 + this.a * dlon * Math.cos(this.lat_ts);
+                        y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts);
+                    } else {
+                        var qs = qsfnz(this.e, Math.sin(lat));
+                        x = this.x0 + this.a * this.k0 * dlon;
+                        y = this.y0 + this.a * qs * 0.5 / this.k0;
+                    }
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    var lon, lat;
+                    if (this.sphere) {
+                        lon = adjust_lon(this.long0 + p.x / this.a / Math.cos(this.lat_ts));
+                        lat = Math.asin(p.y / this.a * Math.cos(this.lat_ts));
+                    } else {
+                        lat = iqsfnz(this.e, 2 * p.y * this.k0 / this.a);
+                        lon = adjust_lon(this.long0 + p.x / (this.a * this.k0));
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = ['cea'];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/iqsfnz': 13,
+                '../common/msfnz': 15,
+                '../common/qsfnz': 20
+            }
+        ],
+        43: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var adjust_lat = _dereq_('../common/adjust_lat');
+                exports.init = function () {
+                    this.x0 = this.x0 || 0;
+                    this.y0 = this.y0 || 0;
+                    this.lat0 = this.lat0 || 0;
+                    this.long0 = this.long0 || 0;
+                    this.lat_ts = this.lat_ts || 0;
+                    this.title = this.title || 'Equidistant Cylindrical (Plate Carre)';
+                    this.rc = Math.cos(this.lat_ts);
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var dlon = adjust_lon(lon - this.long0);
+                    var dlat = adjust_lat(lat - this.lat0);
+                    p.x = this.x0 + this.a * dlon * this.rc;
+                    p.y = this.y0 + this.a * dlat;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var x = p.x;
+                    var y = p.y;
+                    p.x = adjust_lon(this.long0 + (x - this.x0) / (this.a * this.rc));
+                    p.y = adjust_lat(this.lat0 + (y - this.y0) / this.a);
+                    return p;
+                };
+                exports.names = [
+                    'Equirectangular',
+                    'Equidistant_Cylindrical',
+                    'eqc'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lat': 4,
+                '../common/adjust_lon': 5
+            }
+        ],
+        44: [
+            function (_dereq_, module, exports) {
+                var e0fn = _dereq_('../common/e0fn');
+                var e1fn = _dereq_('../common/e1fn');
+                var e2fn = _dereq_('../common/e2fn');
+                var e3fn = _dereq_('../common/e3fn');
+                var msfnz = _dereq_('../common/msfnz');
+                var mlfn = _dereq_('../common/mlfn');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var adjust_lat = _dereq_('../common/adjust_lat');
+                var imlfn = _dereq_('../common/imlfn');
+                var EPSLN = 1e-10;
+                exports.init = function () {
+                    if (Math.abs(this.lat1 + this.lat2) < EPSLN) {
+                        return;
+                    }
+                    this.lat2 = this.lat2 || this.lat1;
+                    this.temp = this.b / this.a;
+                    this.es = 1 - Math.pow(this.temp, 2);
+                    this.e = Math.sqrt(this.es);
+                    this.e0 = e0fn(this.es);
+                    this.e1 = e1fn(this.es);
+                    this.e2 = e2fn(this.es);
+                    this.e3 = e3fn(this.es);
+                    this.sinphi = Math.sin(this.lat1);
+                    this.cosphi = Math.cos(this.lat1);
+                    this.ms1 = msfnz(this.e, this.sinphi, this.cosphi);
+                    this.ml1 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat1);
+                    if (Math.abs(this.lat1 - this.lat2) < EPSLN) {
+                        this.ns = this.sinphi;
+                    } else {
+                        this.sinphi = Math.sin(this.lat2);
+                        this.cosphi = Math.cos(this.lat2);
+                        this.ms2 = msfnz(this.e, this.sinphi, this.cosphi);
+                        this.ml2 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2);
+                        this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1);
+                    }
+                    this.g = this.ml1 + this.ms1 / this.ns;
+                    this.ml0 = mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
+                    this.rh = this.a * (this.g - this.ml0);
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var rh1;
+                    if (this.sphere) {
+                        rh1 = this.a * (this.g - lat);
+                    } else {
+                        var ml = mlfn(this.e0, this.e1, this.e2, this.e3, lat);
+                        rh1 = this.a * (this.g - ml);
+                    }
+                    var theta = this.ns * adjust_lon(lon - this.long0);
+                    var x = this.x0 + rh1 * Math.sin(theta);
+                    var y = this.y0 + this.rh - rh1 * Math.cos(theta);
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    p.x -= this.x0;
+                    p.y = this.rh - p.y + this.y0;
+                    var con, rh1, lat, lon;
+                    if (this.ns >= 0) {
+                        rh1 = Math.sqrt(p.x * p.x + p.y * p.y);
+                        con = 1;
+                    } else {
+                        rh1 = -Math.sqrt(p.x * p.x + p.y * p.y);
+                        con = -1;
+                    }
+                    var theta = 0;
+                    if (rh1 !== 0) {
+                        theta = Math.atan2(con * p.x, con * p.y);
+                    }
+                    if (this.sphere) {
+                        lon = adjust_lon(this.long0 + theta / this.ns);
+                        lat = adjust_lat(this.g - rh1 / this.a);
+                        p.x = lon;
+                        p.y = lat;
+                        return p;
+                    } else {
+                        var ml = this.g - rh1 / this.a;
+                        lat = imlfn(ml, this.e0, this.e1, this.e2, this.e3);
+                        lon = adjust_lon(this.long0 + theta / this.ns);
+                        p.x = lon;
+                        p.y = lat;
+                        return p;
+                    }
+                };
+                exports.names = [
+                    'Equidistant_Conic',
+                    'eqdc'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lat': 4,
+                '../common/adjust_lon': 5,
+                '../common/e0fn': 7,
+                '../common/e1fn': 8,
+                '../common/e2fn': 9,
+                '../common/e3fn': 10,
+                '../common/imlfn': 12,
+                '../common/mlfn': 14,
+                '../common/msfnz': 15
+            }
+        ],
+        45: [
+            function (_dereq_, module, exports) {
+                var FORTPI = Math.PI / 4;
+                var srat = _dereq_('../common/srat');
+                var HALF_PI = Math.PI / 2;
+                var MAX_ITER = 20;
+                exports.init = function () {
+                    var sphi = Math.sin(this.lat0);
+                    var cphi = Math.cos(this.lat0);
+                    cphi *= cphi;
+                    this.rc = Math.sqrt(1 - this.es) / (1 - this.es * sphi * sphi);
+                    this.C = Math.sqrt(1 + this.es * cphi * cphi / (1 - this.es));
+                    this.phic0 = Math.asin(sphi / this.C);
+                    this.ratexp = 0.5 * this.C * this.e;
+                    this.K = Math.tan(0.5 * this.phic0 + FORTPI) / (Math.pow(Math.tan(0.5 * this.lat0 + FORTPI), this.C) * srat(this.e * sphi, this.ratexp));
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    p.y = 2 * Math.atan(this.K * Math.pow(Math.tan(0.5 * lat + FORTPI), this.C) * srat(this.e * Math.sin(lat), this.ratexp)) - HALF_PI;
+                    p.x = this.C * lon;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var DEL_TOL = 1e-14;
+                    var lon = p.x / this.C;
+                    var lat = p.y;
+                    var num = Math.pow(Math.tan(0.5 * lat + FORTPI) / this.K, 1 / this.C);
+                    for (var i = MAX_ITER; i > 0; --i) {
+                        lat = 2 * Math.atan(num * srat(this.e * Math.sin(p.y), -0.5 * this.e)) - HALF_PI;
+                        if (Math.abs(lat - p.y) < DEL_TOL) {
+                            break;
+                        }
+                        p.y = lat;
+                    }
+                    if (!i) {
+                        return null;
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = ['gauss'];
+                return exports;
+            },
+            { '../common/srat': 22 }
+        ],
+        46: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var EPSLN = 1e-10;
+                var asinz = _dereq_('../common/asinz');
+                exports.init = function () {
+                    this.sin_p14 = Math.sin(this.lat0);
+                    this.cos_p14 = Math.cos(this.lat0);
+                    this.infinity_dist = 1000 * this.a;
+                    this.rc = 1;
+                };
+                exports.forward = function (p) {
+                    var sinphi, cosphi;
+                    var dlon;
+                    var coslon;
+                    var ksp;
+                    var g;
+                    var x, y;
+                    var lon = p.x;
+                    var lat = p.y;
+                    dlon = adjust_lon(lon - this.long0);
+                    sinphi = Math.sin(lat);
+                    cosphi = Math.cos(lat);
+                    coslon = Math.cos(dlon);
+                    g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;
+                    ksp = 1;
+                    if (g > 0 || Math.abs(g) <= EPSLN) {
+                        x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g;
+                        y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g;
+                    } else {
+                        x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon);
+                        y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
+                    }
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var rh;
+                    var sinc, cosc;
+                    var c;
+                    var lon, lat;
+                    p.x = (p.x - this.x0) / this.a;
+                    p.y = (p.y - this.y0) / this.a;
+                    p.x /= this.k0;
+                    p.y /= this.k0;
+                    if (rh = Math.sqrt(p.x * p.x + p.y * p.y)) {
+                        c = Math.atan2(rh, this.rc);
+                        sinc = Math.sin(c);
+                        cosc = Math.cos(c);
+                        lat = asinz(cosc * this.sin_p14 + p.y * sinc * this.cos_p14 / rh);
+                        lon = Math.atan2(p.x * sinc, rh * this.cos_p14 * cosc - p.y * this.sin_p14 * sinc);
+                        lon = adjust_lon(this.long0 + lon);
+                    } else {
+                        lat = this.phic0;
+                        lon = 0;
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = ['gnom'];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/asinz': 6
+            }
+        ],
+        47: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                exports.init = function () {
+                    this.a = 6377397.155;
+                    this.es = 0.006674372230614;
+                    this.e = Math.sqrt(this.es);
+                    if (!this.lat0) {
+                        this.lat0 = 0.863937979737193;
+                    }
+                    if (!this.long0) {
+                        this.long0 = 0.7417649320975901 - 0.308341501185665;
+                    }
+                    if (!this.k0) {
+                        this.k0 = 0.9999;
+                    }
+                    this.s45 = 0.785398163397448;
+                    this.s90 = 2 * this.s45;
+                    this.fi0 = this.lat0;
+                    this.e2 = this.es;
+                    this.e = Math.sqrt(this.e2);
+                    this.alfa = Math.sqrt(1 + this.e2 * Math.pow(Math.cos(this.fi0), 4) / (1 - this.e2));
+                    this.uq = 1.04216856380474;
+                    this.u0 = Math.asin(Math.sin(this.fi0) / this.alfa);
+                    this.g = Math.pow((1 + this.e * Math.sin(this.fi0)) / (1 - this.e * Math.sin(this.fi0)), this.alfa * this.e / 2);
+                    this.k = Math.tan(this.u0 / 2 + this.s45) / Math.pow(Math.tan(this.fi0 / 2 + this.s45), this.alfa) * this.g;
+                    this.k1 = this.k0;
+                    this.n0 = this.a * Math.sqrt(1 - this.e2) / (1 - this.e2 * Math.pow(Math.sin(this.fi0), 2));
+                    this.s0 = 1.37008346281555;
+                    this.n = Math.sin(this.s0);
+                    this.ro0 = this.k1 * this.n0 / Math.tan(this.s0);
+                    this.ad = this.s90 - this.uq;
+                };
+                exports.forward = function (p) {
+                    var gfi, u, deltav, s, d, eps, ro;
+                    var lon = p.x;
+                    var lat = p.y;
+                    var delta_lon = adjust_lon(lon - this.long0);
+                    gfi = Math.pow((1 + this.e * Math.sin(lat)) / (1 - this.e * Math.sin(lat)), this.alfa * this.e / 2);
+                    u = 2 * (Math.atan(this.k * Math.pow(Math.tan(lat / 2 + this.s45), this.alfa) / gfi) - this.s45);
+                    deltav = -delta_lon * this.alfa;
+                    s = Math.asin(Math.cos(this.ad) * Math.sin(u) + Math.sin(this.ad) * Math.cos(u) * Math.cos(deltav));
+                    d = Math.asin(Math.cos(u) * Math.sin(deltav) / Math.cos(s));
+                    eps = this.n * d;
+                    ro = this.ro0 * Math.pow(Math.tan(this.s0 / 2 + this.s45), this.n) / Math.pow(Math.tan(s / 2 + this.s45), this.n);
+                    p.y = ro * Math.cos(eps) / 1;
+                    p.x = ro * Math.sin(eps) / 1;
+                    if (!this.czech) {
+                        p.y *= -1;
+                        p.x *= -1;
+                    }
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var u, deltav, s, d, eps, ro, fi1;
+                    var ok;
+                    var tmp = p.x;
+                    p.x = p.y;
+                    p.y = tmp;
+                    if (!this.czech) {
+                        p.y *= -1;
+                        p.x *= -1;
+                    }
+                    ro = Math.sqrt(p.x * p.x + p.y * p.y);
+                    eps = Math.atan2(p.y, p.x);
+                    d = eps / Math.sin(this.s0);
+                    s = 2 * (Math.atan(Math.pow(this.ro0 / ro, 1 / this.n) * Math.tan(this.s0 / 2 + this.s45)) - this.s45);
+                    u = Math.asin(Math.cos(this.ad) * Math.sin(s) - Math.sin(this.ad) * Math.cos(s) * Math.cos(d));
+                    deltav = Math.asin(Math.cos(s) * Math.sin(d) / Math.cos(u));
+                    p.x = this.long0 - deltav / this.alfa;
+                    fi1 = u;
+                    ok = 0;
+                    var iter = 0;
+                    do {
+                        p.y = 2 * (Math.atan(Math.pow(this.k, -1 / this.alfa) * Math.pow(Math.tan(u / 2 + this.s45), 1 / this.alfa) * Math.pow((1 + this.e * Math.sin(fi1)) / (1 - this.e * Math.sin(fi1)), this.e / 2)) - this.s45);
+                        if (Math.abs(fi1 - p.y) < 1e-10) {
+                            ok = 1;
+                        }
+                        fi1 = p.y;
+                        iter += 1;
+                    } while (ok === 0 && iter < 15);
+                    if (iter >= 15) {
+                        return null;
+                    }
+                    return p;
+                };
+                exports.names = [
+                    'Krovak',
+                    'krovak'
+                ];
+                return exports;
+            },
+            { '../common/adjust_lon': 5 }
+        ],
+        48: [
+            function (_dereq_, module, exports) {
+                var HALF_PI = Math.PI / 2;
+                var FORTPI = Math.PI / 4;
+                var EPSLN = 1e-10;
+                var qsfnz = _dereq_('../common/qsfnz');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                exports.S_POLE = 1;
+                exports.N_POLE = 2;
+                exports.EQUIT = 3;
+                exports.OBLIQ = 4;
+                exports.init = function () {
+                    var t = Math.abs(this.lat0);
+                    if (Math.abs(t - HALF_PI) < EPSLN) {
+                        this.mode = this.lat0 < 0 ? this.S_POLE : this.N_POLE;
+                    } else if (Math.abs(t) < EPSLN) {
+                        this.mode = this.EQUIT;
+                    } else {
+                        this.mode = this.OBLIQ;
+                    }
+                    if (this.es > 0) {
+                        var sinphi;
+                        this.qp = qsfnz(this.e, 1);
+                        this.mmf = 0.5 / (1 - this.es);
+                        this.apa = this.authset(this.es);
+                        switch (this.mode) {
+                        case this.N_POLE:
+                            this.dd = 1;
+                            break;
+                        case this.S_POLE:
+                            this.dd = 1;
+                            break;
+                        case this.EQUIT:
+                            this.rq = Math.sqrt(0.5 * this.qp);
+                            this.dd = 1 / this.rq;
+                            this.xmf = 1;
+                            this.ymf = 0.5 * this.qp;
+                            break;
+                        case this.OBLIQ:
+                            this.rq = Math.sqrt(0.5 * this.qp);
+                            sinphi = Math.sin(this.lat0);
+                            this.sinb1 = qsfnz(this.e, sinphi) / this.qp;
+                            this.cosb1 = Math.sqrt(1 - this.sinb1 * this.sinb1);
+                            this.dd = Math.cos(this.lat0) / (Math.sqrt(1 - this.es * sinphi * sinphi) * this.rq * this.cosb1);
+                            this.ymf = (this.xmf = this.rq) / this.dd;
+                            this.xmf *= this.dd;
+                            break;
+                        }
+                    } else {
+                        if (this.mode === this.OBLIQ) {
+                            this.sinph0 = Math.sin(this.lat0);
+                            this.cosph0 = Math.cos(this.lat0);
+                        }
+                    }
+                };
+                exports.forward = function (p) {
+                    var x, y, coslam, sinlam, sinphi, q, sinb, cosb, b, cosphi;
+                    var lam = p.x;
+                    var phi = p.y;
+                    lam = adjust_lon(lam - this.long0);
+                    if (this.sphere) {
+                        sinphi = Math.sin(phi);
+                        cosphi = Math.cos(phi);
+                        coslam = Math.cos(lam);
+                        if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
+                            y = this.mode === this.EQUIT ? 1 + cosphi * coslam : 1 + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;
+                            if (y <= EPSLN) {
+                                return null;
+                            }
+                            y = Math.sqrt(2 / y);
+                            x = y * cosphi * Math.sin(lam);
+                            y *= this.mode === this.EQUIT ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;
+                        } else if (this.mode === this.N_POLE || this.mode === this.S_POLE) {
+                            if (this.mode === this.N_POLE) {
+                                coslam = -coslam;
+                            }
+                            if (Math.abs(phi + this.phi0) < EPSLN) {
+                                return null;
+                            }
+                            y = FORTPI - phi * 0.5;
+                            y = 2 * (this.mode === this.S_POLE ? Math.cos(y) : Math.sin(y));
+                            x = y * Math.sin(lam);
+                            y *= coslam;
+                        }
+                    } else {
+                        sinb = 0;
+                        cosb = 0;
+                        b = 0;
+                        coslam = Math.cos(lam);
+                        sinlam = Math.sin(lam);
+                        sinphi = Math.sin(phi);
+                        q = qsfnz(this.e, sinphi);
+                        if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
+                            sinb = q / this.qp;
+                            cosb = Math.sqrt(1 - sinb * sinb);
+                        }
+                        switch (this.mode) {
+                        case this.OBLIQ:
+                            b = 1 + this.sinb1 * sinb + this.cosb1 * cosb * coslam;
+                            break;
+                        case this.EQUIT:
+                            b = 1 + cosb * coslam;
+                            break;
+                        case this.N_POLE:
+                            b = HALF_PI + phi;
+                            q = this.qp - q;
+                            break;
+                        case this.S_POLE:
+                            b = phi - HALF_PI;
+                            q = this.qp + q;
+                            break;
+                        }
+                        if (Math.abs(b) < EPSLN) {
+                            return null;
+                        }
+                        switch (this.mode) {
+                        case this.OBLIQ:
+                        case this.EQUIT:
+                            b = Math.sqrt(2 / b);
+                            if (this.mode === this.OBLIQ) {
+                                y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam);
+                            } else {
+                                y = (b = Math.sqrt(2 / (1 + cosb * coslam))) * sinb * this.ymf;
+                            }
+                            x = this.xmf * b * cosb * sinlam;
+                            break;
+                        case this.N_POLE:
+                        case this.S_POLE:
+                            if (q >= 0) {
+                                x = (b = Math.sqrt(q)) * sinlam;
+                                y = coslam * (this.mode === this.S_POLE ? b : -b);
+                            } else {
+                                x = y = 0;
+                            }
+                            break;
+                        }
+                    }
+                    p.x = this.a * x + this.x0;
+                    p.y = this.a * y + this.y0;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    var x = p.x / this.a;
+                    var y = p.y / this.a;
+                    var lam, phi, cCe, sCe, q, rho, ab;
+                    if (this.sphere) {
+                        var cosz = 0, rh, sinz = 0;
+                        rh = Math.sqrt(x * x + y * y);
+                        phi = rh * 0.5;
+                        if (phi > 1) {
+                            return null;
+                        }
+                        phi = 2 * Math.asin(phi);
+                        if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
+                            sinz = Math.sin(phi);
+                            cosz = Math.cos(phi);
+                        }
+                        switch (this.mode) {
+                        case this.EQUIT:
+                            phi = Math.abs(rh) <= EPSLN ? 0 : Math.asin(y * sinz / rh);
+                            x *= sinz;
+                            y = cosz * rh;
+                            break;
+                        case this.OBLIQ:
+                            phi = Math.abs(rh) <= EPSLN ? this.phi0 : Math.asin(cosz * this.sinph0 + y * sinz * this.cosph0 / rh);
+                            x *= sinz * this.cosph0;
+                            y = (cosz - Math.sin(phi) * this.sinph0) * rh;
+                            break;
+                        case this.N_POLE:
+                            y = -y;
+                            phi = HALF_PI - phi;
+                            break;
+                        case this.S_POLE:
+                            phi -= HALF_PI;
+                            break;
+                        }
+                        lam = y === 0 && (this.mode === this.EQUIT || this.mode === this.OBLIQ) ? 0 : Math.atan2(x, y);
+                    } else {
+                        ab = 0;
+                        if (this.mode === this.OBLIQ || this.mode === this.EQUIT) {
+                            x /= this.dd;
+                            y *= this.dd;
+                            rho = Math.sqrt(x * x + y * y);
+                            if (rho < EPSLN) {
+                                p.x = 0;
+                                p.y = this.phi0;
+                                return p;
+                            }
+                            sCe = 2 * Math.asin(0.5 * rho / this.rq);
+                            cCe = Math.cos(sCe);
+                            x *= sCe = Math.sin(sCe);
+                            if (this.mode === this.OBLIQ) {
+                                ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho;
+                                q = this.qp * ab;
+                                y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe;
+                            } else {
+                                ab = y * sCe / rho;
+                                q = this.qp * ab;
+                                y = rho * cCe;
+                            }
+                        } else if (this.mode === this.N_POLE || this.mode === this.S_POLE) {
+                            if (this.mode === this.N_POLE) {
+                                y = -y;
+                            }
+                            q = x * x + y * y;
+                            if (!q) {
+                                p.x = 0;
+                                p.y = this.phi0;
+                                return p;
+                            }
+                            ab = 1 - q / this.qp;
+                            if (this.mode === this.S_POLE) {
+                                ab = -ab;
+                            }
+                        }
+                        lam = Math.atan2(x, y);
+                        phi = this.authlat(Math.asin(ab), this.apa);
+                    }
+                    p.x = adjust_lon(this.long0 + lam);
+                    p.y = phi;
+                    return p;
+                };
+                exports.P00 = 0.3333333333333333;
+                exports.P01 = 0.17222222222222222;
+                exports.P02 = 0.10257936507936508;
+                exports.P10 = 0.06388888888888888;
+                exports.P11 = 0.0664021164021164;
+                exports.P20 = 0.016415012942191543;
+                exports.authset = function (es) {
+                    var t;
+                    var APA = [];
+                    APA[0] = es * this.P00;
+                    t = es * es;
+                    APA[0] += t * this.P01;
+                    APA[1] = t * this.P10;
+                    t *= es;
+                    APA[0] += t * this.P02;
+                    APA[1] += t * this.P11;
+                    APA[2] = t * this.P20;
+                    return APA;
+                };
+                exports.authlat = function (beta, APA) {
+                    var t = beta + beta;
+                    return beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t + t) + APA[2] * Math.sin(t + t + t);
+                };
+                exports.names = [
+                    'Lambert Azimuthal Equal Area',
+                    'Lambert_Azimuthal_Equal_Area',
+                    'laea'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/qsfnz': 20
+            }
+        ],
+        49: [
+            function (_dereq_, module, exports) {
+                var EPSLN = 1e-10;
+                var msfnz = _dereq_('../common/msfnz');
+                var tsfnz = _dereq_('../common/tsfnz');
+                var HALF_PI = Math.PI / 2;
+                var sign = _dereq_('../common/sign');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var phi2z = _dereq_('../common/phi2z');
+                exports.init = function () {
+                    if (!this.lat2) {
+                        this.lat2 = this.lat1;
+                    }
+                    if (!this.k0) {
+                        this.k0 = 1;
+                    }
+                    this.x0 = this.x0 || 0;
+                    this.y0 = this.y0 || 0;
+                    if (Math.abs(this.lat1 + this.lat2) < EPSLN) {
+                        return;
+                    }
+                    var temp = this.b / this.a;
+                    this.e = Math.sqrt(1 - temp * temp);
+                    var sin1 = Math.sin(this.lat1);
+                    var cos1 = Math.cos(this.lat1);
+                    var ms1 = msfnz(this.e, sin1, cos1);
+                    var ts1 = tsfnz(this.e, this.lat1, sin1);
+                    var sin2 = Math.sin(this.lat2);
+                    var cos2 = Math.cos(this.lat2);
+                    var ms2 = msfnz(this.e, sin2, cos2);
+                    var ts2 = tsfnz(this.e, this.lat2, sin2);
+                    var ts0 = tsfnz(this.e, this.lat0, Math.sin(this.lat0));
+                    if (Math.abs(this.lat1 - this.lat2) > EPSLN) {
+                        this.ns = Math.log(ms1 / ms2) / Math.log(ts1 / ts2);
+                    } else {
+                        this.ns = sin1;
+                    }
+                    if (isNaN(this.ns)) {
+                        this.ns = sin1;
+                    }
+                    this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns));
+                    this.rh = this.a * this.f0 * Math.pow(ts0, this.ns);
+                    if (!this.title) {
+                        this.title = 'Lambert Conformal Conic';
+                    }
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    if (Math.abs(2 * Math.abs(lat) - Math.PI) <= EPSLN) {
+                        lat = sign(lat) * (HALF_PI - 2 * EPSLN);
+                    }
+                    var con = Math.abs(Math.abs(lat) - HALF_PI);
+                    var ts, rh1;
+                    if (con > EPSLN) {
+                        ts = tsfnz(this.e, lat, Math.sin(lat));
+                        rh1 = this.a * this.f0 * Math.pow(ts, this.ns);
+                    } else {
+                        con = lat * this.ns;
+                        if (con <= 0) {
+                            return null;
+                        }
+                        rh1 = 0;
+                    }
+                    var theta = this.ns * adjust_lon(lon - this.long0);
+                    p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0;
+                    p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var rh1, con, ts;
+                    var lat, lon;
+                    var x = (p.x - this.x0) / this.k0;
+                    var y = this.rh - (p.y - this.y0) / this.k0;
+                    if (this.ns > 0) {
+                        rh1 = Math.sqrt(x * x + y * y);
+                        con = 1;
+                    } else {
+                        rh1 = -Math.sqrt(x * x + y * y);
+                        con = -1;
+                    }
+                    var theta = 0;
+                    if (rh1 !== 0) {
+                        theta = Math.atan2(con * x, con * y);
+                    }
+                    if (rh1 !== 0 || this.ns > 0) {
+                        con = 1 / this.ns;
+                        ts = Math.pow(rh1 / (this.a * this.f0), con);
+                        lat = phi2z(this.e, ts);
+                        if (lat === -9999) {
+                            return null;
+                        }
+                    } else {
+                        lat = -HALF_PI;
+                    }
+                    lon = adjust_lon(theta / this.ns + this.long0);
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Lambert Tangential Conformal Conic Projection',
+                    'Lambert_Conformal_Conic',
+                    'Lambert_Conformal_Conic_2SP',
+                    'lcc'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/msfnz': 15,
+                '../common/phi2z': 16,
+                '../common/sign': 21,
+                '../common/tsfnz': 24
+            }
+        ],
+        50: [
+            function (_dereq_, module, exports) {
+                exports.init = function () {
+                };
+                function identity(pt) {
+                    return pt;
+                }
+                exports.forward = identity;
+                exports.inverse = identity;
+                exports.names = [
+                    'longlat',
+                    'identity'
+                ];
+                return exports;
+            },
+            {}
+        ],
+        51: [
+            function (_dereq_, module, exports) {
+                var msfnz = _dereq_('../common/msfnz');
+                var HALF_PI = Math.PI / 2;
+                var EPSLN = 1e-10;
+                var R2D = 57.29577951308232;
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var FORTPI = Math.PI / 4;
+                var tsfnz = _dereq_('../common/tsfnz');
+                var phi2z = _dereq_('../common/phi2z');
+                exports.init = function () {
+                    var con = this.b / this.a;
+                    this.es = 1 - con * con;
+                    if (!('x0' in this)) {
+                        this.x0 = 0;
+                    }
+                    if (!('y0' in this)) {
+                        this.y0 = 0;
+                    }
+                    this.e = Math.sqrt(this.es);
+                    if (this.lat_ts) {
+                        if (this.sphere) {
+                            this.k0 = Math.cos(this.lat_ts);
+                        } else {
+                            this.k0 = msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
+                        }
+                    } else {
+                        if (!this.k0) {
+                            if (this.k) {
+                                this.k0 = this.k;
+                            } else {
+                                this.k0 = 1;
+                            }
+                        }
+                    }
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    if (lat * R2D > 90 && lat * R2D < -90 && lon * R2D > 180 && lon * R2D < -180) {
+                        return null;
+                    }
+                    var x, y;
+                    if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
+                        return null;
+                    } else {
+                        if (this.sphere) {
+                            x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
+                            y = this.y0 + this.a * this.k0 * Math.log(Math.tan(FORTPI + 0.5 * lat));
+                        } else {
+                            var sinphi = Math.sin(lat);
+                            var ts = tsfnz(this.e, lat, sinphi);
+                            x = this.x0 + this.a * this.k0 * adjust_lon(lon - this.long0);
+                            y = this.y0 - this.a * this.k0 * Math.log(ts);
+                        }
+                        p.x = x;
+                        p.y = y;
+                        return p;
+                    }
+                };
+                exports.inverse = function (p) {
+                    var x = p.x - this.x0;
+                    var y = p.y - this.y0;
+                    var lon, lat;
+                    if (this.sphere) {
+                        lat = HALF_PI - 2 * Math.atan(Math.exp(-y / (this.a * this.k0)));
+                    } else {
+                        var ts = Math.exp(-y / (this.a * this.k0));
+                        lat = phi2z(this.e, ts);
+                        if (lat === -9999) {
+                            return null;
+                        }
+                    }
+                    lon = adjust_lon(this.long0 + x / (this.a * this.k0));
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Mercator',
+                    'Popular Visualisation Pseudo Mercator',
+                    'Mercator_1SP',
+                    'Mercator_Auxiliary_Sphere',
+                    'merc'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/msfnz': 15,
+                '../common/phi2z': 16,
+                '../common/tsfnz': 24
+            }
+        ],
+        52: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                exports.init = function () {
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var dlon = adjust_lon(lon - this.long0);
+                    var x = this.x0 + this.a * dlon;
+                    var y = this.y0 + this.a * Math.log(Math.tan(Math.PI / 4 + lat / 2.5)) * 1.25;
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    var lon = adjust_lon(this.long0 + p.x / this.a);
+                    var lat = 2.5 * (Math.atan(Math.exp(0.8 * p.y / this.a)) - Math.PI / 4);
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Miller_Cylindrical',
+                    'mill'
+                ];
+                return exports;
+            },
+            { '../common/adjust_lon': 5 }
+        ],
+        53: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var EPSLN = 1e-10;
+                exports.init = function () {
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var delta_lon = adjust_lon(lon - this.long0);
+                    var theta = lat;
+                    var con = Math.PI * Math.sin(lat);
+                    for (var i = 0; true; i++) {
+                        var delta_theta = -(theta + Math.sin(theta) - con) / (1 + Math.cos(theta));
+                        theta += delta_theta;
+                        if (Math.abs(delta_theta) < EPSLN) {
+                            break;
+                        }
+                    }
+                    theta /= 2;
+                    if (Math.PI / 2 - Math.abs(lat) < EPSLN) {
+                        delta_lon = 0;
+                    }
+                    var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0;
+                    var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0;
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var theta;
+                    var arg;
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    arg = p.y / (1.4142135623731 * this.a);
+                    if (Math.abs(arg) > 0.999999999999) {
+                        arg = 0.999999999999;
+                    }
+                    theta = Math.asin(arg);
+                    var lon = adjust_lon(this.long0 + p.x / (0.900316316158 * this.a * Math.cos(theta)));
+                    if (lon < -Math.PI) {
+                        lon = -Math.PI;
+                    }
+                    if (lon > Math.PI) {
+                        lon = Math.PI;
+                    }
+                    arg = (2 * theta + Math.sin(2 * theta)) / Math.PI;
+                    if (Math.abs(arg) > 1) {
+                        arg = 1;
+                    }
+                    var lat = Math.asin(arg);
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Mollweide',
+                    'moll'
+                ];
+                return exports;
+            },
+            { '../common/adjust_lon': 5 }
+        ],
+        54: [
+            function (_dereq_, module, exports) {
+                var SEC_TO_RAD = 0.00000484813681109536;
+                exports.iterations = 1;
+                exports.init = function () {
+                    this.A = [];
+                    this.A[1] = 0.6399175073;
+                    this.A[2] = -0.1358797613;
+                    this.A[3] = 0.063294409;
+                    this.A[4] = -0.02526853;
+                    this.A[5] = 0.0117879;
+                    this.A[6] = -0.0055161;
+                    this.A[7] = 0.0026906;
+                    this.A[8] = -0.001333;
+                    this.A[9] = 0.00067;
+                    this.A[10] = -0.00034;
+                    this.B_re = [];
+                    this.B_im = [];
+                    this.B_re[1] = 0.7557853228;
+                    this.B_im[1] = 0;
+                    this.B_re[2] = 0.249204646;
+                    this.B_im[2] = 0.003371507;
+                    this.B_re[3] = -0.001541739;
+                    this.B_im[3] = 0.04105856;
+                    this.B_re[4] = -0.10162907;
+                    this.B_im[4] = 0.01727609;
+                    this.B_re[5] = -0.26623489;
+                    this.B_im[5] = -0.36249218;
+                    this.B_re[6] = -0.6870983;
+                    this.B_im[6] = -1.1651967;
+                    this.C_re = [];
+                    this.C_im = [];
+                    this.C_re[1] = 1.3231270439;
+                    this.C_im[1] = 0;
+                    this.C_re[2] = -0.577245789;
+                    this.C_im[2] = -0.007809598;
+                    this.C_re[3] = 0.508307513;
+                    this.C_im[3] = -0.112208952;
+                    this.C_re[4] = -0.15094762;
+                    this.C_im[4] = 0.18200602;
+                    this.C_re[5] = 1.01418179;
+                    this.C_im[5] = 1.64497696;
+                    this.C_re[6] = 1.9660549;
+                    this.C_im[6] = 2.5127645;
+                    this.D = [];
+                    this.D[1] = 1.5627014243;
+                    this.D[2] = 0.5185406398;
+                    this.D[3] = -0.03333098;
+                    this.D[4] = -0.1052906;
+                    this.D[5] = -0.0368594;
+                    this.D[6] = 0.007317;
+                    this.D[7] = 0.0122;
+                    this.D[8] = 0.00394;
+                    this.D[9] = -0.0013;
+                };
+                exports.forward = function (p) {
+                    var n;
+                    var lon = p.x;
+                    var lat = p.y;
+                    var delta_lat = lat - this.lat0;
+                    var delta_lon = lon - this.long0;
+                    var d_phi = delta_lat / SEC_TO_RAD * 0.00001;
+                    var d_lambda = delta_lon;
+                    var d_phi_n = 1;
+                    var d_psi = 0;
+                    for (n = 1; n <= 10; n++) {
+                        d_phi_n = d_phi_n * d_phi;
+                        d_psi = d_psi + this.A[n] * d_phi_n;
+                    }
+                    var th_re = d_psi;
+                    var th_im = d_lambda;
+                    var th_n_re = 1;
+                    var th_n_im = 0;
+                    var th_n_re1;
+                    var th_n_im1;
+                    var z_re = 0;
+                    var z_im = 0;
+                    for (n = 1; n <= 6; n++) {
+                        th_n_re1 = th_n_re * th_re - th_n_im * th_im;
+                        th_n_im1 = th_n_im * th_re + th_n_re * th_im;
+                        th_n_re = th_n_re1;
+                        th_n_im = th_n_im1;
+                        z_re = z_re + this.B_re[n] * th_n_re - this.B_im[n] * th_n_im;
+                        z_im = z_im + this.B_im[n] * th_n_re + this.B_re[n] * th_n_im;
+                    }
+                    p.x = z_im * this.a + this.x0;
+                    p.y = z_re * this.a + this.y0;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var n;
+                    var x = p.x;
+                    var y = p.y;
+                    var delta_x = x - this.x0;
+                    var delta_y = y - this.y0;
+                    var z_re = delta_y / this.a;
+                    var z_im = delta_x / this.a;
+                    var z_n_re = 1;
+                    var z_n_im = 0;
+                    var z_n_re1;
+                    var z_n_im1;
+                    var th_re = 0;
+                    var th_im = 0;
+                    for (n = 1; n <= 6; n++) {
+                        z_n_re1 = z_n_re * z_re - z_n_im * z_im;
+                        z_n_im1 = z_n_im * z_re + z_n_re * z_im;
+                        z_n_re = z_n_re1;
+                        z_n_im = z_n_im1;
+                        th_re = th_re + this.C_re[n] * z_n_re - this.C_im[n] * z_n_im;
+                        th_im = th_im + this.C_im[n] * z_n_re + this.C_re[n] * z_n_im;
+                    }
+                    for (var i = 0; i < this.iterations; i++) {
+                        var th_n_re = th_re;
+                        var th_n_im = th_im;
+                        var th_n_re1;
+                        var th_n_im1;
+                        var num_re = z_re;
+                        var num_im = z_im;
+                        for (n = 2; n <= 6; n++) {
+                            th_n_re1 = th_n_re * th_re - th_n_im * th_im;
+                            th_n_im1 = th_n_im * th_re + th_n_re * th_im;
+                            th_n_re = th_n_re1;
+                            th_n_im = th_n_im1;
+                            num_re = num_re + (n - 1) * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im);
+                            num_im = num_im + (n - 1) * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im);
+                        }
+                        th_n_re = 1;
+                        th_n_im = 0;
+                        var den_re = this.B_re[1];
+                        var den_im = this.B_im[1];
+                        for (n = 2; n <= 6; n++) {
+                            th_n_re1 = th_n_re * th_re - th_n_im * th_im;
+                            th_n_im1 = th_n_im * th_re + th_n_re * th_im;
+                            th_n_re = th_n_re1;
+                            th_n_im = th_n_im1;
+                            den_re = den_re + n * (this.B_re[n] * th_n_re - this.B_im[n] * th_n_im);
+                            den_im = den_im + n * (this.B_im[n] * th_n_re + this.B_re[n] * th_n_im);
+                        }
+                        var den2 = den_re * den_re + den_im * den_im;
+                        th_re = (num_re * den_re + num_im * den_im) / den2;
+                        th_im = (num_im * den_re - num_re * den_im) / den2;
+                    }
+                    var d_psi = th_re;
+                    var d_lambda = th_im;
+                    var d_psi_n = 1;
+                    var d_phi = 0;
+                    for (n = 1; n <= 9; n++) {
+                        d_psi_n = d_psi_n * d_psi;
+                        d_phi = d_phi + this.D[n] * d_psi_n;
+                    }
+                    var lat = this.lat0 + d_phi * SEC_TO_RAD * 100000;
+                    var lon = this.long0 + d_lambda;
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'New_Zealand_Map_Grid',
+                    'nzmg'
+                ];
+                return exports;
+            },
+            {}
+        ],
+        55: [
+            function (_dereq_, module, exports) {
+                var tsfnz = _dereq_('../common/tsfnz');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var phi2z = _dereq_('../common/phi2z');
+                var HALF_PI = Math.PI / 2;
+                var FORTPI = Math.PI / 4;
+                var EPSLN = 1e-10;
+                exports.init = function () {
+                    this.no_off = this.no_off || false;
+                    this.no_rot = this.no_rot || false;
+                    if (isNaN(this.k0)) {
+                        this.k0 = 1;
+                    }
+                    var sinlat = Math.sin(this.lat0);
+                    var coslat = Math.cos(this.lat0);
+                    var con = this.e * sinlat;
+                    this.bl = Math.sqrt(1 + this.es / (1 - this.es) * Math.pow(coslat, 4));
+                    this.al = this.a * this.bl * this.k0 * Math.sqrt(1 - this.es) / (1 - con * con);
+                    var t0 = tsfnz(this.e, this.lat0, sinlat);
+                    var dl = this.bl / coslat * Math.sqrt((1 - this.es) / (1 - con * con));
+                    if (dl * dl < 1) {
+                        dl = 1;
+                    }
+                    var fl;
+                    var gl;
+                    if (!isNaN(this.longc)) {
+                        if (this.lat0 >= 0) {
+                            fl = dl + Math.sqrt(dl * dl - 1);
+                        } else {
+                            fl = dl - Math.sqrt(dl * dl - 1);
+                        }
+                        this.el = fl * Math.pow(t0, this.bl);
+                        gl = 0.5 * (fl - 1 / fl);
+                        this.gamma0 = Math.asin(Math.sin(this.alpha) / dl);
+                        this.long0 = this.longc - Math.asin(gl * Math.tan(this.gamma0)) / this.bl;
+                    } else {
+                        var t1 = tsfnz(this.e, this.lat1, Math.sin(this.lat1));
+                        var t2 = tsfnz(this.e, this.lat2, Math.sin(this.lat2));
+                        if (this.lat0 >= 0) {
+                            this.el = (dl + Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl);
+                        } else {
+                            this.el = (dl - Math.sqrt(dl * dl - 1)) * Math.pow(t0, this.bl);
+                        }
+                        var hl = Math.pow(t1, this.bl);
+                        var ll = Math.pow(t2, this.bl);
+                        fl = this.el / hl;
+                        gl = 0.5 * (fl - 1 / fl);
+                        var jl = (this.el * this.el - ll * hl) / (this.el * this.el + ll * hl);
+                        var pl = (ll - hl) / (ll + hl);
+                        var dlon12 = adjust_lon(this.long1 - this.long2);
+                        this.long0 = 0.5 * (this.long1 + this.long2) - Math.atan(jl * Math.tan(0.5 * this.bl * dlon12) / pl) / this.bl;
+                        this.long0 = adjust_lon(this.long0);
+                        var dlon10 = adjust_lon(this.long1 - this.long0);
+                        this.gamma0 = Math.atan(Math.sin(this.bl * dlon10) / gl);
+                        this.alpha = Math.asin(dl * Math.sin(this.gamma0));
+                    }
+                    if (this.no_off) {
+                        this.uc = 0;
+                    } else {
+                        if (this.lat0 >= 0) {
+                            this.uc = this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha));
+                        } else {
+                            this.uc = -1 * this.al / this.bl * Math.atan2(Math.sqrt(dl * dl - 1), Math.cos(this.alpha));
+                        }
+                    }
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var dlon = adjust_lon(lon - this.long0);
+                    var us, vs;
+                    var con;
+                    if (Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
+                        if (lat > 0) {
+                            con = -1;
+                        } else {
+                            con = 1;
+                        }
+                        vs = this.al / this.bl * Math.log(Math.tan(FORTPI + con * this.gamma0 * 0.5));
+                        us = -1 * con * HALF_PI * this.al / this.bl;
+                    } else {
+                        var t = tsfnz(this.e, lat, Math.sin(lat));
+                        var ql = this.el / Math.pow(t, this.bl);
+                        var sl = 0.5 * (ql - 1 / ql);
+                        var tl = 0.5 * (ql + 1 / ql);
+                        var vl = Math.sin(this.bl * dlon);
+                        var ul = (sl * Math.sin(this.gamma0) - vl * Math.cos(this.gamma0)) / tl;
+                        if (Math.abs(Math.abs(ul) - 1) <= EPSLN) {
+                            vs = Number.POSITIVE_INFINITY;
+                        } else {
+                            vs = 0.5 * this.al * Math.log((1 - ul) / (1 + ul)) / this.bl;
+                        }
+                        if (Math.abs(Math.cos(this.bl * dlon)) <= EPSLN) {
+                            us = this.al * this.bl * dlon;
+                        } else {
+                            us = this.al * Math.atan2(sl * Math.cos(this.gamma0) + vl * Math.sin(this.gamma0), Math.cos(this.bl * dlon)) / this.bl;
+                        }
+                    }
+                    if (this.no_rot) {
+                        p.x = this.x0 + us;
+                        p.y = this.y0 + vs;
+                    } else {
+                        us -= this.uc;
+                        p.x = this.x0 + vs * Math.cos(this.alpha) + us * Math.sin(this.alpha);
+                        p.y = this.y0 + us * Math.cos(this.alpha) - vs * Math.sin(this.alpha);
+                    }
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var us, vs;
+                    if (this.no_rot) {
+                        vs = p.y - this.y0;
+                        us = p.x - this.x0;
+                    } else {
+                        vs = (p.x - this.x0) * Math.cos(this.alpha) - (p.y - this.y0) * Math.sin(this.alpha);
+                        us = (p.y - this.y0) * Math.cos(this.alpha) + (p.x - this.x0) * Math.sin(this.alpha);
+                        us += this.uc;
+                    }
+                    var qp = Math.exp(-1 * this.bl * vs / this.al);
+                    var sp = 0.5 * (qp - 1 / qp);
+                    var tp = 0.5 * (qp + 1 / qp);
+                    var vp = Math.sin(this.bl * us / this.al);
+                    var up = (vp * Math.cos(this.gamma0) + sp * Math.sin(this.gamma0)) / tp;
+                    var ts = Math.pow(this.el / Math.sqrt((1 + up) / (1 - up)), 1 / this.bl);
+                    if (Math.abs(up - 1) < EPSLN) {
+                        p.x = this.long0;
+                        p.y = HALF_PI;
+                    } else if (Math.abs(up + 1) < EPSLN) {
+                        p.x = this.long0;
+                        p.y = -1 * HALF_PI;
+                    } else {
+                        p.y = phi2z(this.e, ts);
+                        p.x = adjust_lon(this.long0 - Math.atan2(sp * Math.cos(this.gamma0) - vp * Math.sin(this.gamma0), Math.cos(this.bl * us / this.al)) / this.bl);
+                    }
+                    return p;
+                };
+                exports.names = [
+                    'Hotine_Oblique_Mercator',
+                    'Hotine Oblique Mercator',
+                    'Hotine_Oblique_Mercator_Azimuth_Natural_Origin',
+                    'Hotine_Oblique_Mercator_Azimuth_Center',
+                    'omerc'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/phi2z': 16,
+                '../common/tsfnz': 24
+            }
+        ],
+        56: [
+            function (_dereq_, module, exports) {
+                var e0fn = _dereq_('../common/e0fn');
+                var e1fn = _dereq_('../common/e1fn');
+                var e2fn = _dereq_('../common/e2fn');
+                var e3fn = _dereq_('../common/e3fn');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var adjust_lat = _dereq_('../common/adjust_lat');
+                var mlfn = _dereq_('../common/mlfn');
+                var EPSLN = 1e-10;
+                var gN = _dereq_('../common/gN');
+                var MAX_ITER = 20;
+                exports.init = function () {
+                    this.temp = this.b / this.a;
+                    this.es = 1 - Math.pow(this.temp, 2);
+                    this.e = Math.sqrt(this.es);
+                    this.e0 = e0fn(this.es);
+                    this.e1 = e1fn(this.es);
+                    this.e2 = e2fn(this.es);
+                    this.e3 = e3fn(this.es);
+                    this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var x, y, el;
+                    var dlon = adjust_lon(lon - this.long0);
+                    el = dlon * Math.sin(lat);
+                    if (this.sphere) {
+                        if (Math.abs(lat) <= EPSLN) {
+                            x = this.a * dlon;
+                            y = -1 * this.a * this.lat0;
+                        } else {
+                            x = this.a * Math.sin(el) / Math.tan(lat);
+                            y = this.a * (adjust_lat(lat - this.lat0) + (1 - Math.cos(el)) / Math.tan(lat));
+                        }
+                    } else {
+                        if (Math.abs(lat) <= EPSLN) {
+                            x = this.a * dlon;
+                            y = -1 * this.ml0;
+                        } else {
+                            var nl = gN(this.a, this.e, Math.sin(lat)) / Math.tan(lat);
+                            x = nl * Math.sin(el);
+                            y = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat) - this.ml0 + nl * (1 - Math.cos(el));
+                        }
+                    }
+                    p.x = x + this.x0;
+                    p.y = y + this.y0;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var lon, lat, x, y, i;
+                    var al, bl;
+                    var phi, dphi;
+                    x = p.x - this.x0;
+                    y = p.y - this.y0;
+                    if (this.sphere) {
+                        if (Math.abs(y + this.a * this.lat0) <= EPSLN) {
+                            lon = adjust_lon(x / this.a + this.long0);
+                            lat = 0;
+                        } else {
+                            al = this.lat0 + y / this.a;
+                            bl = x * x / this.a / this.a + al * al;
+                            phi = al;
+                            var tanphi;
+                            for (i = MAX_ITER; i; --i) {
+                                tanphi = Math.tan(phi);
+                                dphi = -1 * (al * (phi * tanphi + 1) - phi - 0.5 * (phi * phi + bl) * tanphi) / ((phi - al) / tanphi - 1);
+                                phi += dphi;
+                                if (Math.abs(dphi) <= EPSLN) {
+                                    lat = phi;
+                                    break;
+                                }
+                            }
+                            lon = adjust_lon(this.long0 + Math.asin(x * Math.tan(phi) / this.a) / Math.sin(lat));
+                        }
+                    } else {
+                        if (Math.abs(y + this.ml0) <= EPSLN) {
+                            lat = 0;
+                            lon = adjust_lon(this.long0 + x / this.a);
+                        } else {
+                            al = (this.ml0 + y) / this.a;
+                            bl = x * x / this.a / this.a + al * al;
+                            phi = al;
+                            var cl, mln, mlnp, ma;
+                            var con;
+                            for (i = MAX_ITER; i; --i) {
+                                con = this.e * Math.sin(phi);
+                                cl = Math.sqrt(1 - con * con) * Math.tan(phi);
+                                mln = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, phi);
+                                mlnp = this.e0 - 2 * this.e1 * Math.cos(2 * phi) + 4 * this.e2 * Math.cos(4 * phi) - 6 * this.e3 * Math.cos(6 * phi);
+                                ma = mln / this.a;
+                                dphi = (al * (cl * ma + 1) - ma - 0.5 * cl * (ma * ma + bl)) / (this.es * Math.sin(2 * phi) * (ma * ma + bl - 2 * al * ma) / (4 * cl) + (al - ma) * (cl * mlnp - 2 / Math.sin(2 * phi)) - mlnp);
+                                phi -= dphi;
+                                if (Math.abs(dphi) <= EPSLN) {
+                                    lat = phi;
+                                    break;
+                                }
+                            }
+                            cl = Math.sqrt(1 - this.es * Math.pow(Math.sin(lat), 2)) * Math.tan(lat);
+                            lon = adjust_lon(this.long0 + Math.asin(x * cl / this.a) / Math.sin(lat));
+                        }
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Polyconic',
+                    'poly'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lat': 4,
+                '../common/adjust_lon': 5,
+                '../common/e0fn': 7,
+                '../common/e1fn': 8,
+                '../common/e2fn': 9,
+                '../common/e3fn': 10,
+                '../common/gN': 11,
+                '../common/mlfn': 14
+            }
+        ],
+        57: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var adjust_lat = _dereq_('../common/adjust_lat');
+                var pj_enfn = _dereq_('../common/pj_enfn');
+                var MAX_ITER = 20;
+                var pj_mlfn = _dereq_('../common/pj_mlfn');
+                var pj_inv_mlfn = _dereq_('../common/pj_inv_mlfn');
+                var HALF_PI = Math.PI / 2;
+                var EPSLN = 1e-10;
+                var asinz = _dereq_('../common/asinz');
+                exports.init = function () {
+                    if (!this.sphere) {
+                        this.en = pj_enfn(this.es);
+                    } else {
+                        this.n = 1;
+                        this.m = 0;
+                        this.es = 0;
+                        this.C_y = Math.sqrt((this.m + 1) / this.n);
+                        this.C_x = this.C_y / (this.m + 1);
+                    }
+                };
+                exports.forward = function (p) {
+                    var x, y;
+                    var lon = p.x;
+                    var lat = p.y;
+                    lon = adjust_lon(lon - this.long0);
+                    if (this.sphere) {
+                        if (!this.m) {
+                            lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat;
+                        } else {
+                            var k = this.n * Math.sin(lat);
+                            for (var i = MAX_ITER; i; --i) {
+                                var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat));
+                                lat -= V;
+                                if (Math.abs(V) < EPSLN) {
+                                    break;
+                                }
+                            }
+                        }
+                        x = this.a * this.C_x * lon * (this.m + Math.cos(lat));
+                        y = this.a * this.C_y * lat;
+                    } else {
+                        var s = Math.sin(lat);
+                        var c = Math.cos(lat);
+                        y = this.a * pj_mlfn(lat, s, c, this.en);
+                        x = this.a * lon * c / Math.sqrt(1 - this.es * s * s);
+                    }
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var lat, temp, lon, s;
+                    p.x -= this.x0;
+                    lon = p.x / this.a;
+                    p.y -= this.y0;
+                    lat = p.y / this.a;
+                    if (this.sphere) {
+                        lat /= this.C_y;
+                        lon = lon / (this.C_x * (this.m + Math.cos(lat)));
+                        if (this.m) {
+                            lat = asinz((this.m * lat + Math.sin(lat)) / this.n);
+                        } else if (this.n !== 1) {
+                            lat = asinz(Math.sin(lat) / this.n);
+                        }
+                        lon = adjust_lon(lon + this.long0);
+                        lat = adjust_lat(lat);
+                    } else {
+                        lat = pj_inv_mlfn(p.y / this.a, this.es, this.en);
+                        s = Math.abs(lat);
+                        if (s < HALF_PI) {
+                            s = Math.sin(lat);
+                            temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat));
+                            lon = adjust_lon(temp);
+                        } else if (s - EPSLN < HALF_PI) {
+                            lon = this.long0;
+                        }
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Sinusoidal',
+                    'sinu'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lat': 4,
+                '../common/adjust_lon': 5,
+                '../common/asinz': 6,
+                '../common/pj_enfn': 17,
+                '../common/pj_inv_mlfn': 18,
+                '../common/pj_mlfn': 19
+            }
+        ],
+        58: [
+            function (_dereq_, module, exports) {
+                exports.init = function () {
+                    var phy0 = this.lat0;
+                    this.lambda0 = this.long0;
+                    var sinPhy0 = Math.sin(phy0);
+                    var semiMajorAxis = this.a;
+                    var invF = this.rf;
+                    var flattening = 1 / invF;
+                    var e2 = 2 * flattening - Math.pow(flattening, 2);
+                    var e = this.e = Math.sqrt(e2);
+                    this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2));
+                    this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4));
+                    this.b0 = Math.asin(sinPhy0 / this.alpha);
+                    var k1 = Math.log(Math.tan(Math.PI / 4 + this.b0 / 2));
+                    var k2 = Math.log(Math.tan(Math.PI / 4 + phy0 / 2));
+                    var k3 = Math.log((1 + e * sinPhy0) / (1 - e * sinPhy0));
+                    this.K = k1 - this.alpha * k2 + this.alpha * e / 2 * k3;
+                };
+                exports.forward = function (p) {
+                    var Sa1 = Math.log(Math.tan(Math.PI / 4 - p.y / 2));
+                    var Sa2 = this.e / 2 * Math.log((1 + this.e * Math.sin(p.y)) / (1 - this.e * Math.sin(p.y)));
+                    var S = -this.alpha * (Sa1 + Sa2) + this.K;
+                    var b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4);
+                    var I = this.alpha * (p.x - this.lambda0);
+                    var rotI = Math.atan(Math.sin(I) / (Math.sin(this.b0) * Math.tan(b) + Math.cos(this.b0) * Math.cos(I)));
+                    var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - Math.sin(this.b0) * Math.cos(b) * Math.cos(I));
+                    p.y = this.R / 2 * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + this.y0;
+                    p.x = this.R * rotI + this.x0;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var Y = p.x - this.x0;
+                    var X = p.y - this.y0;
+                    var rotI = Y / this.R;
+                    var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4);
+                    var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI));
+                    var I = Math.atan(Math.sin(rotI) / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) * Math.tan(rotB)));
+                    var lambda = this.lambda0 + I / this.alpha;
+                    var S = 0;
+                    var phy = b;
+                    var prevPhy = -1000;
+                    var iteration = 0;
+                    while (Math.abs(phy - prevPhy) > 1e-7) {
+                        if (++iteration > 20) {
+                            return;
+                        }
+                        S = 1 / this.alpha * (Math.log(Math.tan(Math.PI / 4 + b / 2)) - this.K) + this.e * Math.log(Math.tan(Math.PI / 4 + Math.asin(this.e * Math.sin(phy)) / 2));
+                        prevPhy = phy;
+                        phy = 2 * Math.atan(Math.exp(S)) - Math.PI / 2;
+                    }
+                    p.x = lambda;
+                    p.y = phy;
+                    return p;
+                };
+                exports.names = ['somerc'];
+                return exports;
+            },
+            {}
+        ],
+        59: [
+            function (_dereq_, module, exports) {
+                var HALF_PI = Math.PI / 2;
+                var EPSLN = 1e-10;
+                var sign = _dereq_('../common/sign');
+                var msfnz = _dereq_('../common/msfnz');
+                var tsfnz = _dereq_('../common/tsfnz');
+                var phi2z = _dereq_('../common/phi2z');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                exports.ssfn_ = function (phit, sinphi, eccen) {
+                    sinphi *= eccen;
+                    return Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen);
+                };
+                exports.init = function () {
+                    this.coslat0 = Math.cos(this.lat0);
+                    this.sinlat0 = Math.sin(this.lat0);
+                    if (this.sphere) {
+                        if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
+                            this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts));
+                        }
+                    } else {
+                        if (Math.abs(this.coslat0) <= EPSLN) {
+                            if (this.lat0 > 0) {
+                                this.con = 1;
+                            } else {
+                                this.con = -1;
+                            }
+                        }
+                        this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e));
+                        if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
+                            this.k0 = 0.5 * this.cons * msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)) / tsfnz(this.e, this.con * this.lat_ts, this.con * Math.sin(this.lat_ts));
+                        }
+                        this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0);
+                        this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI;
+                        this.cosX0 = Math.cos(this.X0);
+                        this.sinX0 = Math.sin(this.X0);
+                    }
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var sinlat = Math.sin(lat);
+                    var coslat = Math.cos(lat);
+                    var A, X, sinX, cosX, ts, rh;
+                    var dlon = adjust_lon(lon - this.long0);
+                    if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) {
+                        p.x = NaN;
+                        p.y = NaN;
+                        return p;
+                    }
+                    if (this.sphere) {
+                        A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon));
+                        p.x = this.a * A * coslat * Math.sin(dlon) + this.x0;
+                        p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0;
+                        return p;
+                    } else {
+                        X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI;
+                        cosX = Math.cos(X);
+                        sinX = Math.sin(X);
+                        if (Math.abs(this.coslat0) <= EPSLN) {
+                            ts = tsfnz(this.e, lat * this.con, this.con * sinlat);
+                            rh = 2 * this.a * this.k0 * ts / this.cons;
+                            p.x = this.x0 + rh * Math.sin(lon - this.long0);
+                            p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0);
+                            return p;
+                        } else if (Math.abs(this.sinlat0) < EPSLN) {
+                            A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon));
+                            p.y = A * sinX;
+                        } else {
+                            A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon)));
+                            p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0;
+                        }
+                        p.x = A * cosX * Math.sin(dlon) + this.x0;
+                    }
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    var lon, lat, ts, ce, Chi;
+                    var rh = Math.sqrt(p.x * p.x + p.y * p.y);
+                    if (this.sphere) {
+                        var c = 2 * Math.atan(rh / (0.5 * this.a * this.k0));
+                        lon = this.long0;
+                        lat = this.lat0;
+                        if (rh <= EPSLN) {
+                            p.x = lon;
+                            p.y = lat;
+                            return p;
+                        }
+                        lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh);
+                        if (Math.abs(this.coslat0) < EPSLN) {
+                            if (this.lat0 > 0) {
+                                lon = adjust_lon(this.long0 + Math.atan2(p.x, -1 * p.y));
+                            } else {
+                                lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));
+                            }
+                        } else {
+                            lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(c), rh * this.coslat0 * Math.cos(c) - p.y * this.sinlat0 * Math.sin(c)));
+                        }
+                        p.x = lon;
+                        p.y = lat;
+                        return p;
+                    } else {
+                        if (Math.abs(this.coslat0) <= EPSLN) {
+                            if (rh <= EPSLN) {
+                                lat = this.lat0;
+                                lon = this.long0;
+                                p.x = lon;
+                                p.y = lat;
+                                return p;
+                            }
+                            p.x *= this.con;
+                            p.y *= this.con;
+                            ts = rh * this.cons / (2 * this.a * this.k0);
+                            lat = this.con * phi2z(this.e, ts);
+                            lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, -1 * p.y));
+                        } else {
+                            ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1));
+                            lon = this.long0;
+                            if (rh <= EPSLN) {
+                                Chi = this.X0;
+                            } else {
+                                Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh);
+                                lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(ce), rh * this.cosX0 * Math.cos(ce) - p.y * this.sinX0 * Math.sin(ce)));
+                            }
+                            lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi)));
+                        }
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = ['stere'];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/msfnz': 15,
+                '../common/phi2z': 16,
+                '../common/sign': 21,
+                '../common/tsfnz': 24
+            }
+        ],
+        60: [
+            function (_dereq_, module, exports) {
+                var gauss = _dereq_('./gauss');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                exports.init = function () {
+                    gauss.init.apply(this);
+                    if (!this.rc) {
+                        return;
+                    }
+                    this.sinc0 = Math.sin(this.phic0);
+                    this.cosc0 = Math.cos(this.phic0);
+                    this.R2 = 2 * this.rc;
+                    if (!this.title) {
+                        this.title = 'Oblique Stereographic Alternative';
+                    }
+                };
+                exports.forward = function (p) {
+                    var sinc, cosc, cosl, k;
+                    p.x = adjust_lon(p.x - this.long0);
+                    gauss.forward.apply(this, [p]);
+                    sinc = Math.sin(p.y);
+                    cosc = Math.cos(p.y);
+                    cosl = Math.cos(p.x);
+                    k = this.k0 * this.R2 / (1 + this.sinc0 * sinc + this.cosc0 * cosc * cosl);
+                    p.x = k * cosc * Math.sin(p.x);
+                    p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl);
+                    p.x = this.a * p.x + this.x0;
+                    p.y = this.a * p.y + this.y0;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var sinc, cosc, lon, lat, rho;
+                    p.x = (p.x - this.x0) / this.a;
+                    p.y = (p.y - this.y0) / this.a;
+                    p.x /= this.k0;
+                    p.y /= this.k0;
+                    if (rho = Math.sqrt(p.x * p.x + p.y * p.y)) {
+                        var c = 2 * Math.atan2(rho, this.R2);
+                        sinc = Math.sin(c);
+                        cosc = Math.cos(c);
+                        lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho);
+                        lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc);
+                    } else {
+                        lat = this.phic0;
+                        lon = 0;
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    gauss.inverse.apply(this, [p]);
+                    p.x = adjust_lon(p.x + this.long0);
+                    return p;
+                };
+                exports.names = [
+                    'Stereographic_North_Pole',
+                    'Oblique_Stereographic',
+                    'Polar_Stereographic',
+                    'sterea',
+                    'Oblique Stereographic Alternative'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                './gauss': 45
+            }
+        ],
+        61: [
+            function (_dereq_, module, exports) {
+                var e0fn = _dereq_('../common/e0fn');
+                var e1fn = _dereq_('../common/e1fn');
+                var e2fn = _dereq_('../common/e2fn');
+                var e3fn = _dereq_('../common/e3fn');
+                var mlfn = _dereq_('../common/mlfn');
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var HALF_PI = Math.PI / 2;
+                var EPSLN = 1e-10;
+                var sign = _dereq_('../common/sign');
+                var asinz = _dereq_('../common/asinz');
+                exports.init = function () {
+                    this.e0 = e0fn(this.es);
+                    this.e1 = e1fn(this.es);
+                    this.e2 = e2fn(this.es);
+                    this.e3 = e3fn(this.es);
+                    this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var delta_lon = adjust_lon(lon - this.long0);
+                    var con;
+                    var x, y;
+                    var sin_phi = Math.sin(lat);
+                    var cos_phi = Math.cos(lat);
+                    if (this.sphere) {
+                        var b = cos_phi * Math.sin(delta_lon);
+                        if (Math.abs(Math.abs(b) - 1) < 1e-10) {
+                            return 93;
+                        } else {
+                            x = 0.5 * this.a * this.k0 * Math.log((1 + b) / (1 - b));
+                            con = Math.acos(cos_phi * Math.cos(delta_lon) / Math.sqrt(1 - b * b));
+                            if (lat < 0) {
+                                con = -con;
+                            }
+                            y = this.a * this.k0 * (con - this.lat0);
+                        }
+                    } else {
+                        var al = cos_phi * delta_lon;
+                        var als = Math.pow(al, 2);
+                        var c = this.ep2 * Math.pow(cos_phi, 2);
+                        var tq = Math.tan(lat);
+                        var t = Math.pow(tq, 2);
+                        con = 1 - this.es * Math.pow(sin_phi, 2);
+                        var n = this.a / Math.sqrt(con);
+                        var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat);
+                        x = this.k0 * n * al * (1 + als / 6 * (1 - t + c + als / 20 * (5 - 18 * t + Math.pow(t, 2) + 72 * c - 58 * this.ep2))) + this.x0;
+                        y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24 * (5 - t + 9 * c + 4 * Math.pow(c, 2) + als / 30 * (61 - 58 * t + Math.pow(t, 2) + 600 * c - 330 * this.ep2))))) + this.y0;
+                    }
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var con, phi;
+                    var delta_phi;
+                    var i;
+                    var max_iter = 6;
+                    var lat, lon;
+                    if (this.sphere) {
+                        var f = Math.exp(p.x / (this.a * this.k0));
+                        var g = 0.5 * (f - 1 / f);
+                        var temp = this.lat0 + p.y / (this.a * this.k0);
+                        var h = Math.cos(temp);
+                        con = Math.sqrt((1 - h * h) / (1 + g * g));
+                        lat = asinz(con);
+                        if (temp < 0) {
+                            lat = -lat;
+                        }
+                        if (g === 0 && h === 0) {
+                            lon = this.long0;
+                        } else {
+                            lon = adjust_lon(Math.atan2(g, h) + this.long0);
+                        }
+                    } else {
+                        var x = p.x - this.x0;
+                        var y = p.y - this.y0;
+                        con = (this.ml0 + y / this.k0) / this.a;
+                        phi = con;
+                        for (i = 0; true; i++) {
+                            delta_phi = (con + this.e1 * Math.sin(2 * phi) - this.e2 * Math.sin(4 * phi) + this.e3 * Math.sin(6 * phi)) / this.e0 - phi;
+                            phi += delta_phi;
+                            if (Math.abs(delta_phi) <= EPSLN) {
+                                break;
+                            }
+                            if (i >= max_iter) {
+                                return 95;
+                            }
+                        }
+                        if (Math.abs(phi) < HALF_PI) {
+                            var sin_phi = Math.sin(phi);
+                            var cos_phi = Math.cos(phi);
+                            var tan_phi = Math.tan(phi);
+                            var c = this.ep2 * Math.pow(cos_phi, 2);
+                            var cs = Math.pow(c, 2);
+                            var t = Math.pow(tan_phi, 2);
+                            var ts = Math.pow(t, 2);
+                            con = 1 - this.es * Math.pow(sin_phi, 2);
+                            var n = this.a / Math.sqrt(con);
+                            var r = n * (1 - this.es) / con;
+                            var d = x / (n * this.k0);
+                            var ds = Math.pow(d, 2);
+                            lat = phi - n * tan_phi * ds / r * (0.5 - ds / 24 * (5 + 3 * t + 10 * c - 4 * cs - 9 * this.ep2 - ds / 30 * (61 + 90 * t + 298 * c + 45 * ts - 252 * this.ep2 - 3 * cs)));
+                            lon = adjust_lon(this.long0 + d * (1 - ds / 6 * (1 + 2 * t + c - ds / 20 * (5 - 2 * c + 28 * t - 3 * cs + 8 * this.ep2 + 24 * ts))) / cos_phi);
+                        } else {
+                            lat = HALF_PI * sign(y);
+                            lon = this.long0;
+                        }
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Transverse_Mercator',
+                    'Transverse Mercator',
+                    'tmerc'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/asinz': 6,
+                '../common/e0fn': 7,
+                '../common/e1fn': 8,
+                '../common/e2fn': 9,
+                '../common/e3fn': 10,
+                '../common/mlfn': 14,
+                '../common/sign': 21
+            }
+        ],
+        62: [
+            function (_dereq_, module, exports) {
+                var D2R = 0.017453292519943295;
+                var tmerc = _dereq_('./tmerc');
+                exports.dependsOn = 'tmerc';
+                exports.init = function () {
+                    if (!this.zone) {
+                        return;
+                    }
+                    this.lat0 = 0;
+                    this.long0 = (6 * Math.abs(this.zone) - 183) * D2R;
+                    this.x0 = 500000;
+                    this.y0 = this.utmSouth ? 10000000 : 0;
+                    this.k0 = 0.9996;
+                    tmerc.init.apply(this);
+                    this.forward = tmerc.forward;
+                    this.inverse = tmerc.inverse;
+                };
+                exports.names = [
+                    'Universal Transverse Mercator System',
+                    'utm'
+                ];
+                return exports;
+            },
+            { './tmerc': 61 }
+        ],
+        63: [
+            function (_dereq_, module, exports) {
+                var adjust_lon = _dereq_('../common/adjust_lon');
+                var HALF_PI = Math.PI / 2;
+                var EPSLN = 1e-10;
+                var asinz = _dereq_('../common/asinz');
+                exports.init = function () {
+                    this.R = this.a;
+                };
+                exports.forward = function (p) {
+                    var lon = p.x;
+                    var lat = p.y;
+                    var dlon = adjust_lon(lon - this.long0);
+                    var x, y;
+                    if (Math.abs(lat) <= EPSLN) {
+                        x = this.x0 + this.R * dlon;
+                        y = this.y0;
+                    }
+                    var theta = asinz(2 * Math.abs(lat / Math.PI));
+                    if (Math.abs(dlon) <= EPSLN || Math.abs(Math.abs(lat) - HALF_PI) <= EPSLN) {
+                        x = this.x0;
+                        if (lat >= 0) {
+                            y = this.y0 + Math.PI * this.R * Math.tan(0.5 * theta);
+                        } else {
+                            y = this.y0 + Math.PI * this.R * -Math.tan(0.5 * theta);
+                        }
+                    }
+                    var al = 0.5 * Math.abs(Math.PI / dlon - dlon / Math.PI);
+                    var asq = al * al;
+                    var sinth = Math.sin(theta);
+                    var costh = Math.cos(theta);
+                    var g = costh / (sinth + costh - 1);
+                    var gsq = g * g;
+                    var m = g * (2 / sinth - 1);
+                    var msq = m * m;
+                    var con = Math.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq);
+                    if (dlon < 0) {
+                        con = -con;
+                    }
+                    x = this.x0 + con;
+                    var q = asq + g;
+                    con = Math.PI * this.R * (m * q - al * Math.sqrt((msq + asq) * (asq + 1) - q * q)) / (msq + asq);
+                    if (lat >= 0) {
+                        y = this.y0 + con;
+                    } else {
+                        y = this.y0 - con;
+                    }
+                    p.x = x;
+                    p.y = y;
+                    return p;
+                };
+                exports.inverse = function (p) {
+                    var lon, lat;
+                    var xx, yy, xys, c1, c2, c3;
+                    var a1;
+                    var m1;
+                    var con;
+                    var th1;
+                    var d;
+                    p.x -= this.x0;
+                    p.y -= this.y0;
+                    con = Math.PI * this.R;
+                    xx = p.x / con;
+                    yy = p.y / con;
+                    xys = xx * xx + yy * yy;
+                    c1 = -Math.abs(yy) * (1 + xys);
+                    c2 = c1 - 2 * yy * yy + xx * xx;
+                    c3 = -2 * c1 + 1 + 2 * yy * yy + xys * xys;
+                    d = yy * yy / c3 + (2 * c2 * c2 * c2 / c3 / c3 / c3 - 9 * c1 * c2 / c3 / c3) / 27;
+                    a1 = (c1 - c2 * c2 / 3 / c3) / c3;
+                    m1 = 2 * Math.sqrt(-a1 / 3);
+                    con = 3 * d / a1 / m1;
+                    if (Math.abs(con) > 1) {
+                        if (con >= 0) {
+                            con = 1;
+                        } else {
+                            con = -1;
+                        }
+                    }
+                    th1 = Math.acos(con) / 3;
+                    if (p.y >= 0) {
+                        lat = (-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI;
+                    } else {
+                        lat = -(-m1 * Math.cos(th1 + Math.PI / 3) - c2 / 3 / c3) * Math.PI;
+                    }
+                    if (Math.abs(xx) < EPSLN) {
+                        lon = this.long0;
+                    } else {
+                        lon = adjust_lon(this.long0 + Math.PI * (xys - 1 + Math.sqrt(1 + 2 * (xx * xx - yy * yy) + xys * xys)) / 2 / xx);
+                    }
+                    p.x = lon;
+                    p.y = lat;
+                    return p;
+                };
+                exports.names = [
+                    'Van_der_Grinten_I',
+                    'VanDerGrinten',
+                    'vandg'
+                ];
+                return exports;
+            },
+            {
+                '../common/adjust_lon': 5,
+                '../common/asinz': 6
+            }
+        ],
+        64: [
+            function (_dereq_, module, exports) {
+                var D2R = 0.017453292519943295;
+                var R2D = 57.29577951308232;
+                var PJD_3PARAM = 1;
+                var PJD_7PARAM = 2;
+                var datum_transform = _dereq_('./datum_transform');
+                var adjust_axis = _dereq_('./adjust_axis');
+                var proj = _dereq_('./Proj');
+                var toPoint = _dereq_('./common/toPoint');
+                module.exports = function transform(source, dest, point) {
+                    var wgs84;
+                    if (Array.isArray(point)) {
+                        point = toPoint(point);
+                    }
+                    function checkNotWGS(source, dest) {
+                        return (source.datum.datum_type === PJD_3PARAM || source.datum.datum_type === PJD_7PARAM) && dest.datumCode !== 'WGS84';
+                    }
+                    if (source.datum && dest.datum && (checkNotWGS(source, dest) || checkNotWGS(dest, source))) {
+                        wgs84 = new proj('WGS84');
+                        transform(source, wgs84, point);
+                        source = wgs84;
+                    }
+                    if (source.axis !== 'enu') {
+                        adjust_axis(source, false, point);
+                    }
+                    if (source.projName === 'longlat') {
+                        point.x *= D2R;
+                        point.y *= D2R;
+                    } else {
+                        if (source.to_meter) {
+                            point.x *= source.to_meter;
+                            point.y *= source.to_meter;
+                        }
+                        source.inverse(point);
+                    }
+                    if (source.from_greenwich) {
+                        point.x += source.from_greenwich;
+                    }
+                    point = datum_transform(source.datum, dest.datum, point);
+                    if (dest.from_greenwich) {
+                        point.x -= dest.from_greenwich;
+                    }
+                    if (dest.projName === 'longlat') {
+                        point.x *= R2D;
+                        point.y *= R2D;
+                    } else {
+                        dest.forward(point);
+                        if (dest.to_meter) {
+                            point.x /= dest.to_meter;
+                            point.y /= dest.to_meter;
+                        }
+                    }
+                    if (dest.axis !== 'enu') {
+                        adjust_axis(dest, true, point);
+                    }
+                    return point;
+                };
+                return exports;
+            },
+            {
+                './Proj': 2,
+                './adjust_axis': 3,
+                './common/toPoint': 23,
+                './datum_transform': 30
+            }
+        ],
+        65: [
+            function (_dereq_, module, exports) {
+                var D2R = 0.017453292519943295;
+                var extend = _dereq_('./extend');
+                function mapit(obj, key, v) {
+                    obj[key] = v.map(function (aa) {
+                        var o = {};
+                        sExpr(aa, o);
+                        return o;
+                    }).reduce(function (a, b) {
+                        return extend(a, b);
+                    }, {});
+                }
+                function sExpr(v, obj) {
+                    var key;
+                    if (!Array.isArray(v)) {
+                        obj[v] = true;
+                        return;
+                    } else {
+                        key = v.shift();
+                        if (key === 'PARAMETER') {
+                            key = v.shift();
+                        }
+                        if (v.length === 1) {
+                            if (Array.isArray(v[0])) {
+                                obj[key] = {};
+                                sExpr(v[0], obj[key]);
+                            } else {
+                                obj[key] = v[0];
+                            }
+                        } else if (!v.length) {
+                            obj[key] = true;
+                        } else if (key === 'TOWGS84') {
+                            obj[key] = v;
+                        } else {
+                            obj[key] = {};
+                            if ([
+                                    'UNIT',
+                                    'PRIMEM',
+                                    'VERT_DATUM'
+                                ].indexOf(key) > -1) {
+                                obj[key] = {
+                                    name: v[0].toLowerCase(),
+                                    convert: v[1]
+                                };
+                                if (v.length === 3) {
+                                    obj[key].auth = v[2];
+                                }
+                            } else if (key === 'SPHEROID') {
+                                obj[key] = {
+                                    name: v[0],
+                                    a: v[1],
+                                    rf: v[2]
+                                };
+                                if (v.length === 4) {
+                                    obj[key].auth = v[3];
+                                }
+                            } else if ([
+                                    'GEOGCS',
+                                    'GEOCCS',
+                                    'DATUM',
+                                    'VERT_CS',
+                                    'COMPD_CS',
+                                    'LOCAL_CS',
+                                    'FITTED_CS',
+                                    'LOCAL_DATUM'
+                                ].indexOf(key) > -1) {
+                                v[0] = [
+                                    'name',
+                                    v[0]
+                                ];
+                                mapit(obj, key, v);
+                            } else if (v.every(function (aa) {
+                                    return Array.isArray(aa);
+                                })) {
+                                mapit(obj, key, v);
+                            } else {
+                                sExpr(v, obj[key]);
+                            }
+                        }
+                    }
+                }
+                function rename(obj, params) {
+                    var outName = params[0];
+                    var inName = params[1];
+                    if (!(outName in obj) && inName in obj) {
+                        obj[outName] = obj[inName];
+                        if (params.length === 3) {
+                            obj[outName] = params[2](obj[outName]);
+                        }
+                    }
+                }
+                function d2r(input) {
+                    return input * D2R;
+                }
+                function cleanWKT(wkt) {
+                    if (wkt.type === 'GEOGCS') {
+                        wkt.projName = 'longlat';
+                    } else if (wkt.type === 'LOCAL_CS') {
+                        wkt.projName = 'identity';
+                        wkt.local = true;
+                    } else {
+                        if (typeof wkt.PROJECTION === 'object') {
+                            wkt.projName = Object.keys(wkt.PROJECTION)[0];
+                        } else {
+                            wkt.projName = wkt.PROJECTION;
+                        }
+                    }
+                    if (wkt.UNIT) {
+                        wkt.units = wkt.UNIT.name.toLowerCase();
+                        if (wkt.units === 'metre') {
+                            wkt.units = 'meter';
+                        }
+                        if (wkt.UNIT.convert) {
+                            wkt.to_meter = parseFloat(wkt.UNIT.convert, 10);
+                        }
+                    }
+                    if (wkt.GEOGCS) {
+                        if (wkt.GEOGCS.DATUM) {
+                            wkt.datumCode = wkt.GEOGCS.DATUM.name.toLowerCase();
+                        } else {
+                            wkt.datumCode = wkt.GEOGCS.name.toLowerCase();
+                        }
+                        if (wkt.datumCode.slice(0, 2) === 'd_') {
+                            wkt.datumCode = wkt.datumCode.slice(2);
+                        }
+                        if (wkt.datumCode === 'new_zealand_geodetic_datum_1949' || wkt.datumCode === 'new_zealand_1949') {
+                            wkt.datumCode = 'nzgd49';
+                        }
+                        if (wkt.datumCode === 'wgs_1984') {
+                            if (wkt.PROJECTION === 'Mercator_Auxiliary_Sphere') {
+                                wkt.sphere = true;
+                            }
+                            wkt.datumCode = 'wgs84';
+                        }
+                        if (wkt.datumCode.slice(-6) === '_ferro') {
+                            wkt.datumCode = wkt.datumCode.slice(0, -6);
+                        }
+                        if (wkt.datumCode.slice(-8) === '_jakarta') {
+                            wkt.datumCode = wkt.datumCode.slice(0, -8);
+                        }
+                        if (~wkt.datumCode.indexOf('belge')) {
+                            wkt.datumCode = 'rnb72';
+                        }
+                        if (wkt.GEOGCS.DATUM && wkt.GEOGCS.DATUM.SPHEROID) {
+                            wkt.ellps = wkt.GEOGCS.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk');
+                            if (wkt.ellps.toLowerCase().slice(0, 13) === 'international') {
+                                wkt.ellps = 'intl';
+                            }
+                            wkt.a = wkt.GEOGCS.DATUM.SPHEROID.a;
+                            wkt.rf = parseFloat(wkt.GEOGCS.DATUM.SPHEROID.rf, 10);
+                        }
+                        if (~wkt.datumCode.indexOf('osgb_1936')) {
+                            wkt.datumCode = 'osgb36';
+                        }
+                    }
+                    if (wkt.b && !isFinite(wkt.b)) {
+                        wkt.b = wkt.a;
+                    }
+                    function toMeter(input) {
+                        var ratio = wkt.to_meter || 1;
+                        return parseFloat(input, 10) * ratio;
+                    }
+                    var renamer = function (a) {
+                        return rename(wkt, a);
+                    };
+                    var list = [
+                        [
+                            'standard_parallel_1',
+                            'Standard_Parallel_1'
+                        ],
+                        [
+                            'standard_parallel_2',
+                            'Standard_Parallel_2'
+                        ],
+                        [
+                            'false_easting',
+                            'False_Easting'
+                        ],
+                        [
+                            'false_northing',
+                            'False_Northing'
+                        ],
+                        [
+                            'central_meridian',
+                            'Central_Meridian'
+                        ],
+                        [
+                            'latitude_of_origin',
+                            'Latitude_Of_Origin'
+                        ],
+                        [
+                            'scale_factor',
+                            'Scale_Factor'
+                        ],
+                        [
+                            'k0',
+                            'scale_factor'
+                        ],
+                        [
+                            'latitude_of_center',
+                            'Latitude_of_center'
+                        ],
+                        [
+                            'lat0',
+                            'latitude_of_center',
+                            d2r
+                        ],
+                        [
+                            'longitude_of_center',
+                            'Longitude_Of_Center'
+                        ],
+                        [
+                            'longc',
+                            'longitude_of_center',
+                            d2r
+                        ],
+                        [
+                            'x0',
+                            'false_easting',
+                            toMeter
+                        ],
+                        [
+                            'y0',
+                            'false_northing',
+                            toMeter
+                        ],
+                        [
+                            'long0',
+                            'central_meridian',
+                            d2r
+                        ],
+                        [
+                            'lat0',
+                            'latitude_of_origin',
+                            d2r
+                        ],
+                        [
+                            'lat0',
+                            'standard_parallel_1',
+                            d2r
+                        ],
+                        [
+                            'lat1',
+                            'standard_parallel_1',
+                            d2r
+                        ],
+                        [
+                            'lat2',
+                            'standard_parallel_2',
+                            d2r
+                        ],
+                        [
+                            'alpha',
+                            'azimuth',
+                            d2r
+                        ],
+                        [
+                            'srsCode',
+                            'name'
+                        ]
+                    ];
+                    list.forEach(renamer);
+                    if (!wkt.long0 && wkt.longc && (wkt.PROJECTION === 'Albers_Conic_Equal_Area' || wkt.PROJECTION === 'Lambert_Azimuthal_Equal_Area')) {
+                        wkt.long0 = wkt.longc;
+                    }
+                }
+                module.exports = function (wkt, self) {
+                    var lisp = JSON.parse((',' + wkt).replace(/\s*\,\s*([A-Z_0-9]+?)(\[)/g, ',["$1",').slice(1).replace(/\s*\,\s*([A-Z_0-9]+?)\]/g, ',"$1"]'));
+                    var type = lisp.shift();
+                    var name = lisp.shift();
+                    lisp.unshift([
+                        'name',
+                        name
+                    ]);
+                    lisp.unshift([
+                        'type',
+                        type
+                    ]);
+                    lisp.unshift('output');
+                    var obj = {};
+                    sExpr(lisp, obj);
+                    cleanWKT(obj.output);
+                    return extend(self, obj.output);
+                };
+                return exports;
+            },
+            { './extend': 33 }
+        ],
+        66: [
+            function (_dereq_, module, exports) {
+                var NUM_100K_SETS = 6;
+                var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS';
+                var SET_ORIGIN_ROW_LETTERS = 'AFAFAF';
+                var A = 65;
+                var I = 73;
+                var O = 79;
+                var V = 86;
+                var Z = 90;
+                exports.forward = function (ll, accuracy) {
+                    accuracy = accuracy || 5;
+                    return encode(LLtoUTM({
+                        lat: ll[1],
+                        lon: ll[0]
+                    }), accuracy);
+                };
+                exports.inverse = function (mgrs) {
+                    var bbox = UTMtoLL(decode(mgrs.toUpperCase()));
+                    return [
+                        bbox.left,
+                        bbox.bottom,
+                        bbox.right,
+                        bbox.top
+                    ];
+                };
+                exports.toPoint = function (mgrsStr) {
+                    var llbbox = exports.inverse(mgrsStr);
+                    return [
+                        (llbbox[2] + llbbox[0]) / 2,
+                        (llbbox[3] + llbbox[1]) / 2
+                    ];
+                };
+                function degToRad(deg) {
+                    return deg * (Math.PI / 180);
+                }
+                function radToDeg(rad) {
+                    return 180 * (rad / Math.PI);
+                }
+                function LLtoUTM(ll) {
+                    var Lat = ll.lat;
+                    var Long = ll.lon;
+                    var a = 6378137;
+                    var eccSquared = 0.00669438;
+                    var k0 = 0.9996;
+                    var LongOrigin;
+                    var eccPrimeSquared;
+                    var N, T, C, A, M;
+                    var LatRad = degToRad(Lat);
+                    var LongRad = degToRad(Long);
+                    var LongOriginRad;
+                    var ZoneNumber;
+                    ZoneNumber = Math.floor((Long + 180) / 6) + 1;
+                    if (Long === 180) {
+                        ZoneNumber = 60;
+                    }
+                    if (Lat >= 56 && Lat < 64 && Long >= 3 && Long < 12) {
+                        ZoneNumber = 32;
+                    }
+                    if (Lat >= 72 && Lat < 84) {
+                        if (Long >= 0 && Long < 9) {
+                            ZoneNumber = 31;
+                        } else if (Long >= 9 && Long < 21) {
+                            ZoneNumber = 33;
+                        } else if (Long >= 21 && Long < 33) {
+                            ZoneNumber = 35;
+                        } else if (Long >= 33 && Long < 42) {
+                            ZoneNumber = 37;
+                        }
+                    }
+                    LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3;
+                    LongOriginRad = degToRad(LongOrigin);
+                    eccPrimeSquared = eccSquared / (1 - eccSquared);
+                    N = a / Math.sqrt(1 - eccSquared * Math.sin(LatRad) * Math.sin(LatRad));
+                    T = Math.tan(LatRad) * Math.tan(LatRad);
+                    C = eccPrimeSquared * Math.cos(LatRad) * Math.cos(LatRad);
+                    A = Math.cos(LatRad) * (LongRad - LongOriginRad);
+                    M = a * ((1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256) * LatRad - (3 * eccSquared / 8 + 3 * eccSquared * eccSquared / 32 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(2 * LatRad) + (15 * eccSquared * eccSquared / 256 + 45 * eccSquared * eccSquared * eccSquared / 1024) * Math.sin(4 * LatRad) - 35 * eccSquared * eccSquared * eccSquared / 3072 * Math.sin(6 * LatRad));
+                    var UTMEasting = k0 * N * (A + (1 - T + C) * A * A * A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120) + 500000;
+                    var UTMNorthing = k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720));
+                    if (Lat < 0) {
+                        UTMNorthing += 10000000;
+                    }
+                    return {
+                        northing: Math.round(UTMNorthing),
+                        easting: Math.round(UTMEasting),
+                        zoneNumber: ZoneNumber,
+                        zoneLetter: getLetterDesignator(Lat)
+                    };
+                }
+                function UTMtoLL(utm) {
+                    var UTMNorthing = utm.northing;
+                    var UTMEasting = utm.easting;
+                    var zoneLetter = utm.zoneLetter;
+                    var zoneNumber = utm.zoneNumber;
+                    if (zoneNumber < 0 || zoneNumber > 60) {
+                        return null;
+                    }
+                    var k0 = 0.9996;
+                    var a = 6378137;
+                    var eccSquared = 0.00669438;
+                    var eccPrimeSquared;
+                    var e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared));
+                    var N1, T1, C1, R1, D, M;
+                    var LongOrigin;
+                    var mu, phi1Rad;
+                    var x = UTMEasting - 500000;
+                    var y = UTMNorthing;
+                    if (zoneLetter < 'N') {
+                        y -= 10000000;
+                    }
+                    LongOrigin = (zoneNumber - 1) * 6 - 180 + 3;
+                    eccPrimeSquared = eccSquared / (1 - eccSquared);
+                    M = y / k0;
+                    mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256));
+                    phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + 151 * e1 * e1 * e1 / 96 * Math.sin(6 * mu);
+                    N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad));
+                    T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad);
+                    C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad);
+                    R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5);
+                    D = x / (N1 * k0);
+                    var lat = phi1Rad - N1 * Math.tan(phi1Rad) / R1 * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720);
+                    lat = radToDeg(lat);
+                    var lon = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad);
+                    lon = LongOrigin + radToDeg(lon);
+                    var result;
+                    if (utm.accuracy) {
+                        var topRight = UTMtoLL({
+                            northing: utm.northing + utm.accuracy,
+                            easting: utm.easting + utm.accuracy,
+                            zoneLetter: utm.zoneLetter,
+                            zoneNumber: utm.zoneNumber
+                        });
+                        result = {
+                            top: topRight.lat,
+                            right: topRight.lon,
+                            bottom: lat,
+                            left: lon
+                        };
+                    } else {
+                        result = {
+                            lat: lat,
+                            lon: lon
+                        };
+                    }
+                    return result;
+                }
+                function getLetterDesignator(lat) {
+                    var LetterDesignator = 'Z';
+                    if (84 >= lat && lat >= 72) {
+                        LetterDesignator = 'X';
+                    } else if (72 > lat && lat >= 64) {
+                        LetterDesignator = 'W';
+                    } else if (64 > lat && lat >= 56) {
+                        LetterDesignator = 'V';
+                    } else if (56 > lat && lat >= 48) {
+                        LetterDesignator = 'U';
+                    } else if (48 > lat && lat >= 40) {
+                        LetterDesignator = 'T';
+                    } else if (40 > lat && lat >= 32) {
+                        LetterDesignator = 'S';
+                    } else if (32 > lat && lat >= 24) {
+                        LetterDesignator = 'R';
+                    } else if (24 > lat && lat >= 16) {
+                        LetterDesignator = 'Q';
+                    } else if (16 > lat && lat >= 8) {
+                        LetterDesignator = 'P';
+                    } else if (8 > lat && lat >= 0) {
+                        LetterDesignator = 'N';
+                    } else if (0 > lat && lat >= -8) {
+                        LetterDesignator = 'M';
+                    } else if (-8 > lat && lat >= -16) {
+                        LetterDesignator = 'L';
+                    } else if (-16 > lat && lat >= -24) {
+                        LetterDesignator = 'K';
+                    } else if (-24 > lat && lat >= -32) {
+                        LetterDesignator = 'J';
+                    } else if (-32 > lat && lat >= -40) {
+                        LetterDesignator = 'H';
+                    } else if (-40 > lat && lat >= -48) {
+                        LetterDesignator = 'G';
+                    } else if (-48 > lat && lat >= -56) {
+                        LetterDesignator = 'F';
+                    } else if (-56 > lat && lat >= -64) {
+                        LetterDesignator = 'E';
+                    } else if (-64 > lat && lat >= -72) {
+                        LetterDesignator = 'D';
+                    } else if (-72 > lat && lat >= -80) {
+                        LetterDesignator = 'C';
+                    }
+                    return LetterDesignator;
+                }
+                function encode(utm, accuracy) {
+                    var seasting = '' + utm.easting, snorthing = '' + utm.northing;
+                    return utm.zoneNumber + utm.zoneLetter + get100kID(utm.easting, utm.northing, utm.zoneNumber) + seasting.substr(seasting.length - 5, accuracy) + snorthing.substr(snorthing.length - 5, accuracy);
+                }
+                function get100kID(easting, northing, zoneNumber) {
+                    var setParm = get100kSetForZone(zoneNumber);
+                    var setColumn = Math.floor(easting / 100000);
+                    var setRow = Math.floor(northing / 100000) % 20;
+                    return getLetter100kID(setColumn, setRow, setParm);
+                }
+                function get100kSetForZone(i) {
+                    var setParm = i % NUM_100K_SETS;
+                    if (setParm === 0) {
+                        setParm = NUM_100K_SETS;
+                    }
+                    return setParm;
+                }
+                function getLetter100kID(column, row, parm) {
+                    var index = parm - 1;
+                    var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index);
+                    var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index);
+                    var colInt = colOrigin + column - 1;
+                    var rowInt = rowOrigin + row;
+                    var rollover = false;
+                    if (colInt > Z) {
+                        colInt = colInt - Z + A - 1;
+                        rollover = true;
+                    }
+                    if (colInt === I || colOrigin < I && colInt > I || (colInt > I || colOrigin < I) && rollover) {
+                        colInt++;
+                    }
+                    if (colInt === O || colOrigin < O && colInt > O || (colInt > O || colOrigin < O) && rollover) {
+                        colInt++;
+                        if (colInt === I) {
+                            colInt++;
+                        }
+                    }
+                    if (colInt > Z) {
+                        colInt = colInt - Z + A - 1;
+                    }
+                    if (rowInt > V) {
+                        rowInt = rowInt - V + A - 1;
+                        rollover = true;
+                    } else {
+                        rollover = false;
+                    }
+                    if (rowInt === I || rowOrigin < I && rowInt > I || (rowInt > I || rowOrigin < I) && rollover) {
+                        rowInt++;
+                    }
+                    if (rowInt === O || rowOrigin < O && rowInt > O || (rowInt > O || rowOrigin < O) && rollover) {
+                        rowInt++;
+                        if (rowInt === I) {
+                            rowInt++;
+                        }
+                    }
+                    if (rowInt > V) {
+                        rowInt = rowInt - V + A - 1;
+                    }
+                    var twoLetter = String.fromCharCode(colInt) + String.fromCharCode(rowInt);
+                    return twoLetter;
+                }
+                function decode(mgrsString) {
+                    if (mgrsString && mgrsString.length === 0) {
+                        throw 'MGRSPoint coverting from nothing';
+                    }
+                    var length = mgrsString.length;
+                    var hunK = null;
+                    var sb = '';
+                    var testChar;
+                    var i = 0;
+                    while (!/[A-Z]/.test(testChar = mgrsString.charAt(i))) {
+                        if (i >= 2) {
+                            throw 'MGRSPoint bad conversion from: ' + mgrsString;
+                        }
+                        sb += testChar;
+                        i++;
+                    }
+                    var zoneNumber = parseInt(sb, 10);
+                    if (i === 0 || i + 3 > length) {
+                        throw 'MGRSPoint bad conversion from: ' + mgrsString;
+                    }
+                    var zoneLetter = mgrsString.charAt(i++);
+                    if (zoneLetter <= 'A' || zoneLetter === 'B' || zoneLetter === 'Y' || zoneLetter >= 'Z' || zoneLetter === 'I' || zoneLetter === 'O') {
+                        throw 'MGRSPoint zone letter ' + zoneLetter + ' not handled: ' + mgrsString;
+                    }
+                    hunK = mgrsString.substring(i, i += 2);
+                    var set = get100kSetForZone(zoneNumber);
+                    var east100k = getEastingFromChar(hunK.charAt(0), set);
+                    var north100k = getNorthingFromChar(hunK.charAt(1), set);
+                    while (north100k < getMinNorthing(zoneLetter)) {
+                        north100k += 2000000;
+                    }
+                    var remainder = length - i;
+                    if (remainder % 2 !== 0) {
+                        throw 'MGRSPoint has to have an even number \nof digits after the zone letter and two 100km letters - front \nhalf for easting meters, second half for \nnorthing meters' + mgrsString;
+                    }
+                    var sep = remainder / 2;
+                    var sepEasting = 0;
+                    var sepNorthing = 0;
+                    var accuracyBonus, sepEastingString, sepNorthingString, easting, northing;
+                    if (sep > 0) {
+                        accuracyBonus = 100000 / Math.pow(10, sep);
+                        sepEastingString = mgrsString.substring(i, i + sep);
+                        sepEasting = parseFloat(sepEastingString) * accuracyBonus;
+                        sepNorthingString = mgrsString.substring(i + sep);
+                        sepNorthing = parseFloat(sepNorthingString) * accuracyBonus;
+                    }
+                    easting = sepEasting + east100k;
+                    northing = sepNorthing + north100k;
+                    return {
+                        easting: easting,
+                        northing: northing,
+                        zoneLetter: zoneLetter,
+                        zoneNumber: zoneNumber,
+                        accuracy: accuracyBonus
+                    };
+                }
+                function getEastingFromChar(e, set) {
+                    var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1);
+                    var eastingValue = 100000;
+                    var rewindMarker = false;
+                    while (curCol !== e.charCodeAt(0)) {
+                        curCol++;
+                        if (curCol === I) {
+                            curCol++;
+                        }
+                        if (curCol === O) {
+                            curCol++;
+                        }
+                        if (curCol > Z) {
+                            if (rewindMarker) {
+                                throw 'Bad character: ' + e;
+                            }
+                            curCol = A;
+                            rewindMarker = true;
+                        }
+                        eastingValue += 100000;
+                    }
+                    return eastingValue;
+                }
+                function getNorthingFromChar(n, set) {
+                    if (n > 'V') {
+                        throw 'MGRSPoint given invalid Northing ' + n;
+                    }
+                    var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1);
+                    var northingValue = 0;
+                    var rewindMarker = false;
+                    while (curRow !== n.charCodeAt(0)) {
+                        curRow++;
+                        if (curRow === I) {
+                            curRow++;
+                        }
+                        if (curRow === O) {
+                            curRow++;
+                        }
+                        if (curRow > V) {
+                            if (rewindMarker) {
+                                throw 'Bad character: ' + n;
+                            }
+                            curRow = A;
+                            rewindMarker = true;
+                        }
+                        northingValue += 100000;
+                    }
+                    return northingValue;
+                }
+                function getMinNorthing(zoneLetter) {
+                    var northing;
+                    switch (zoneLetter) {
+                    case 'C':
+                        northing = 1100000;
+                        break;
+                    case 'D':
+                        northing = 2000000;
+                        break;
+                    case 'E':
+                        northing = 2800000;
+                        break;
+                    case 'F':
+                        northing = 3700000;
+                        break;
+                    case 'G':
+                        northing = 4600000;
+                        break;
+                    case 'H':
+                        northing = 5500000;
+                        break;
+                    case 'J':
+                        northing = 6400000;
+                        break;
+                    case 'K':
+                        northing = 7300000;
+                        break;
+                    case 'L':
+                        northing = 8200000;
+                        break;
+                    case 'M':
+                        northing = 9100000;
+                        break;
+                    case 'N':
+                        northing = 0;
+                        break;
+                    case 'P':
+                        northing = 800000;
+                        break;
+                    case 'Q':
+                        northing = 1700000;
+                        break;
+                    case 'R':
+                        northing = 2600000;
+                        break;
+                    case 'S':
+                        northing = 3500000;
+                        break;
+                    case 'T':
+                        northing = 4400000;
+                        break;
+                    case 'U':
+                        northing = 5300000;
+                        break;
+                    case 'V':
+                        northing = 6200000;
+                        break;
+                    case 'W':
+                        northing = 7000000;
+                        break;
+                    case 'X':
+                        northing = 7900000;
+                        break;
+                    default:
+                        northing = -1;
+                    }
+                    if (northing >= 0) {
+                        return northing;
+                    } else {
+                        throw 'Invalid zone letter: ' + zoneLetter;
+                    }
+                }
+                return exports;
+            },
+            {}
+        ],
+        67: [
+            function (_dereq_, module, exports) {
+                module.exports = {
+                    'name': 'proj4',
+                    'version': '2.2.1',
+                    'description': 'Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.',
+                    'main': 'lib/index.js',
+                    'directories': {
+                        'test': 'test',
+                        'doc': 'docs'
+                    },
+                    'scripts': { 'test': './node_modules/istanbul/lib/cli.js test ./node_modules/mocha/bin/_mocha test/test.js' },
+                    'repository': {
+                        'type': 'git',
+                        'url': 'git://github.com/proj4js/proj4js.git'
+                    },
+                    'author': '',
+                    'license': 'MIT',
+                    'jam': {
+                        'main': 'dist/proj4.js',
+                        'include': [
+                            'dist/proj4.js',
+                            'README.md',
+                            'AUTHORS',
+                            'LICENSE.md'
+                        ]
+                    },
+                    'devDependencies': {
+                        'grunt-cli': '~0.1.13',
+                        'grunt': '~0.4.2',
+                        'grunt-contrib-connect': '~0.6.0',
+                        'grunt-contrib-jshint': '~0.8.0',
+                        'chai': '~1.8.1',
+                        'mocha': '~1.17.1',
+                        'grunt-mocha-phantomjs': '~0.4.0',
+                        'browserify': '~3.24.5',
+                        'grunt-browserify': '~1.3.0',
+                        'grunt-contrib-uglify': '~0.3.2',
+                        'curl': 'git://github.com/cujojs/curl.git',
+                        'istanbul': '~0.2.4',
+                        'tin': '~0.4.0'
+                    },
+                    'dependencies': { 'mgrs': '0.0.0' }
+                };
+                return exports;
+            },
+            {}
+        ],
+        './includedProjections': [
+            function (_dereq_, module, exports) {
+                module.exports = _dereq_('gWUPNW');
+                return exports;
+            },
+            {}
+        ],
+        'gWUPNW': [
+            function (_dereq_, module, exports) {
+                var projs = [
+                    _dereq_('./lib/projections/tmerc'),
+                    _dereq_('./lib/projections/utm'),
+                    _dereq_('./lib/projections/sterea'),
+                    _dereq_('./lib/projections/stere'),
+                    _dereq_('./lib/projections/somerc'),
+                    _dereq_('./lib/projections/omerc'),
+                    _dereq_('./lib/projections/lcc'),
+                    _dereq_('./lib/projections/krovak'),
+                    _dereq_('./lib/projections/cass'),
+                    _dereq_('./lib/projections/laea'),
+                    _dereq_('./lib/projections/aea'),
+                    _dereq_('./lib/projections/gnom'),
+                    _dereq_('./lib/projections/cea'),
+                    _dereq_('./lib/projections/eqc'),
+                    _dereq_('./lib/projections/poly'),
+                    _dereq_('./lib/projections/nzmg'),
+                    _dereq_('./lib/projections/mill'),
+                    _dereq_('./lib/projections/sinu'),
+                    _dereq_('./lib/projections/moll'),
+                    _dereq_('./lib/projections/eqdc'),
+                    _dereq_('./lib/projections/vandg'),
+                    _dereq_('./lib/projections/aeqd')
+                ];
+                module.exports = function (proj4) {
+                    projs.forEach(function (proj) {
+                        proj4.Proj.projections.add(proj);
+                    });
+                };
+                return exports;
+            },
+            {
+                './lib/projections/aea': 39,
+                './lib/projections/aeqd': 40,
+                './lib/projections/cass': 41,
+                './lib/projections/cea': 42,
+                './lib/projections/eqc': 43,
+                './lib/projections/eqdc': 44,
+                './lib/projections/gnom': 46,
+                './lib/projections/krovak': 47,
+                './lib/projections/laea': 48,
+                './lib/projections/lcc': 49,
+                './lib/projections/mill': 52,
+                './lib/projections/moll': 53,
+                './lib/projections/nzmg': 54,
+                './lib/projections/omerc': 55,
+                './lib/projections/poly': 56,
+                './lib/projections/sinu': 57,
+                './lib/projections/somerc': 58,
+                './lib/projections/stere': 59,
+                './lib/projections/sterea': 60,
+                './lib/projections/tmerc': 61,
+                './lib/projections/utm': 62,
+                './lib/projections/vandg': 63
+            }
+        ]
+    }, {}, [35])(35);
+});
+!function (root, factory) {
+    if (true) {
+        proj4leaflet07x = function (leaflet, proj4) {
+            return typeof factory === 'function' ? factory(leaflet, proj4) : factory;
+        }(leaflet, proj4);
+    } else if (typeof module === 'object' && typeof module.exports === 'object') {
+        L = leaflet;
+        proj4 = proj4;
+        module.exports = factory(L, proj4);
+    } else {
+        if (typeof root.L === 'undefined' || typeof root.proj4 === 'undefined')
+            throw 'Leaflet and proj4 must be loaded first';
+        factory(root.L, root.proj4);
+    }
+}(this, function (L, proj4) {
+    L.Proj = {};
+    L.Proj._isProj4Obj = function (a) {
+        return typeof a.inverse !== 'undefined' && typeof a.forward !== 'undefined';
+    };
+    L.Proj.ScaleDependantTransformation = function (scaleTransforms) {
+        this.scaleTransforms = scaleTransforms;
+    };
+    L.Proj.ScaleDependantTransformation.prototype.transform = function (point, scale) {
+        return this.scaleTransforms[scale].transform(point, scale);
+    };
+    L.Proj.ScaleDependantTransformation.prototype.untransform = function (point, scale) {
+        return this.scaleTransforms[scale].untransform(point, scale);
+    };
+    L.Proj.Projection = L.Class.extend({
+        initialize: function (a, def) {
+            if (L.Proj._isProj4Obj(a)) {
+                this._proj = a;
+            } else {
+                var code = a;
+                if (def) {
+                    proj4.defs(code, def);
+                } else if (proj4.defs[code] === undefined) {
+                    var urn = code.split(':');
+                    if (urn.length > 3) {
+                        code = urn[urn.length - 3] + ':' + urn[urn.length - 1];
+                    }
+                    if (proj4.defs[code] === undefined) {
+                        throw 'No projection definition for code ' + code;
+                    }
+                }
+                this._proj = proj4(code);
+            }
+        },
+        project: function (latlng) {
+            var point = this._proj.forward([
+                latlng.lng,
+                latlng.lat
+            ]);
+            return new L.Point(point[0], point[1]);
+        },
+        unproject: function (point, unbounded) {
+            var point2 = this._proj.inverse([
+                point.x,
+                point.y
+            ]);
+            return new L.LatLng(point2[1], point2[0], unbounded);
+        }
+    });
+    L.Proj.CRS = L.Class.extend({
+        includes: L.CRS,
+        options: { transformation: new L.Transformation(1, 0, -1, 0) },
+        initialize: function (a, b, c) {
+            var code, proj, def, options;
+            if (L.Proj._isProj4Obj(a)) {
+                proj = a;
+                code = proj.srsCode;
+                options = b || {};
+                this.projection = new L.Proj.Projection(proj);
+            } else {
+                code = a;
+                def = b;
+                options = c || {};
+                this.projection = new L.Proj.Projection(code, def);
+            }
+            L.Util.setOptions(this, options);
+            this.code = code;
+            this.transformation = this.options.transformation;
+            if (this.options.origin) {
+                this.transformation = new L.Transformation(1, -this.options.origin[0], -1, this.options.origin[1]);
+            }
+            if (this.options.scales) {
+                this._scales = this.options.scales;
+            } else if (this.options.resolutions) {
+                this._scales = [];
+                for (var i = this.options.resolutions.length - 1; i >= 0; i--) {
+                    if (this.options.resolutions[i]) {
+                        this._scales[i] = 1 / this.options.resolutions[i];
+                    }
+                }
+            }
+        },
+        scale: function (zoom) {
+            var iZoom = Math.floor(zoom), baseScale, nextScale, scaleDiff, zDiff;
+            if (zoom === iZoom) {
+                return this._scales[zoom];
+            } else {
+                baseScale = this._scales[iZoom];
+                nextScale = this._scales[iZoom + 1];
+                scaleDiff = nextScale - baseScale;
+                zDiff = zoom - iZoom;
+                return baseScale + scaleDiff * zDiff;
+            }
+        },
+        getSize: function (zoom) {
+            var b = this.options.bounds, s, min, max;
+            if (b) {
+                s = this.scale(zoom);
+                min = this.transformation.transform(b.min, s);
+                max = this.transformation.transform(b.max, s);
+                return L.point(Math.abs(max.x - min.x), Math.abs(max.y - min.y));
+            } else {
+                s = 256 * Math.pow(2, zoom);
+                return L.point(s, s);
+            }
+        }
+    });
+    L.Proj.CRS.TMS = L.Proj.CRS.extend({
+        options: { tileSize: 256 },
+        initialize: function (a, b, c, d) {
+            var code, def, proj, projectedBounds, options;
+            if (L.Proj._isProj4Obj(a)) {
+                proj = a;
+                projectedBounds = b;
+                options = c || {};
+                options.origin = [
+                    projectedBounds[0],
+                    projectedBounds[3]
+                ];
+                L.Proj.CRS.prototype.initialize.call(this, proj, options);
+            } else {
+                code = a;
+                def = b;
+                projectedBounds = c;
+                options = d || {};
+                options.origin = [
+                    projectedBounds[0],
+                    projectedBounds[3]
+                ];
+                L.Proj.CRS.prototype.initialize.call(this, code, def, options);
+            }
+            this.projectedBounds = projectedBounds;
+            this._sizes = this._calculateSizes();
+        },
+        _calculateSizes: function () {
+            var sizes = [], crsBounds = this.projectedBounds, projectedTileSize, i, x, y;
+            for (i = this._scales.length - 1; i >= 0; i--) {
+                if (this._scales[i]) {
+                    projectedTileSize = this.options.tileSize / this._scales[i];
+                    x = Math.ceil(parseFloat((crsBounds[2] - crsBounds[0]) / projectedTileSize).toPrecision(3)) * projectedTileSize * this._scales[i];
+                    y = Math.ceil(parseFloat((crsBounds[3] - crsBounds[1]) / projectedTileSize).toPrecision(3)) * projectedTileSize * this._scales[i];
+                    sizes[i] = L.point(x, y);
+                }
+            }
+            return sizes;
+        },
+        getSize: function (zoom) {
+            return this._sizes[zoom];
+        }
+    });
+    L.Proj.TileLayer = {};
+    L.Proj.TileLayer.TMS = L.TileLayer.extend({
+        options: { continuousWorld: true },
+        initialize: function (urlTemplate, crs, options) {
+            var boundsMatchesGrid = true, scaleTransforms, upperY, crsBounds, i;
+            if (!(crs instanceof L.Proj.CRS.TMS)) {
+                throw 'CRS is not L.Proj.CRS.TMS.';
+            }
+            L.TileLayer.prototype.initialize.call(this, urlTemplate, options);
+            this.options.tms = false;
+            this.crs = crs;
+            crsBounds = this.crs.projectedBounds;
+            for (i = this.options.minZoom; i < this.options.maxZoom && boundsMatchesGrid; i++) {
+                var gridHeight = (crsBounds[3] - crsBounds[1]) / this._projectedTileSize(i);
+                boundsMatchesGrid = Math.abs(gridHeight - Math.round(gridHeight)) > 0.001;
+            }
+            if (!boundsMatchesGrid) {
+                scaleTransforms = {};
+                for (i = this.options.minZoom; i < this.options.maxZoom; i++) {
+                    upperY = crsBounds[1] + Math.ceil((crsBounds[3] - crsBounds[1]) / this._projectedTileSize(i)) * this._projectedTileSize(i);
+                    scaleTransforms[this.crs.scale(i)] = new L.Transformation(1, -crsBounds[0], -1, upperY);
+                }
+                this.crs = new L.Proj.CRS.TMS(this.crs.projection._proj, crsBounds, this.crs.options);
+                this.crs.transformation = new L.Proj.ScaleDependantTransformation(scaleTransforms);
+            }
+        },
+        getTileUrl: function (tilePoint) {
+            var zoom = this._map.getZoom(), gridHeight = Math.ceil((this.crs.projectedBounds[3] - this.crs.projectedBounds[1]) / this._projectedTileSize(zoom));
+            return L.Util.template(this._url, L.Util.extend({
+                s: this._getSubdomain(tilePoint),
+                z: this._getZoomForUrl(),
+                x: tilePoint.x,
+                y: gridHeight - tilePoint.y - 1
+            }, this.options));
+        },
+        _projectedTileSize: function (zoom) {
+            return this.options.tileSize / this.crs.scale(zoom);
+        }
+    });
+    L.Proj.GeoJSON = L.GeoJSON.extend({
+        initialize: function (geojson, options) {
+            this._callLevel = 0;
+            L.GeoJSON.prototype.initialize.call(this, null, options);
+            if (geojson) {
+                this.addData(geojson);
+            }
+        },
+        addData: function (geojson) {
+            var crs;
+            if (geojson) {
+                if (geojson.crs && geojson.crs.type === 'name') {
+                    crs = new L.Proj.CRS(geojson.crs.properties.name);
+                } else if (geojson.crs && geojson.crs.type) {
+                    crs = new L.Proj.CRS(geojson.crs.type + ':' + geojson.crs.properties.code);
+                }
+                if (crs !== undefined) {
+                    this.options.coordsToLatLng = function (coords) {
+                        var point = L.point(coords[0], coords[1]);
+                        return crs.projection.unproject(point);
+                    };
+                }
+            }
+            this._callLevel++;
+            try {
+                L.GeoJSON.prototype.addData.call(this, geojson);
+            } finally {
+                this._callLevel--;
+                if (this._callLevel === 0) {
+                    delete this.options.coordsToLatLng;
+                }
+            }
+        }
+    });
+    L.Proj.geoJson = function (geojson, options) {
+        return new L.Proj.GeoJSON(geojson, options);
+    };
+    L.Proj.ImageOverlay = L.ImageOverlay.extend({
+        initialize: function (url, bounds, options) {
+            L.ImageOverlay.prototype.initialize.call(this, url, null, options);
+            this._projBounds = bounds;
+        },
+        _animateZoom: function (e) {
+            var northwest = L.point(this._projBounds.min.x, this._projBounds.max.y), southeast = L.point(this._projBounds.max.x, this._projBounds.min.y), topLeft = this._projectedToNewLayerPoint(northwest, e.zoom, e.center), size = this._projectedToNewLayerPoint(southeast, e.zoom, e.center).subtract(topLeft), origin = topLeft.add(size._multiplyBy((1 - 1 / e.scale) / 2));
+            this._image.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(origin) + ' scale(' + this._map.getZoomScale(e.zoom) + ') ';
+        },
+        _reset: function () {
+            var zoom = this._map.getZoom(), pixelOrigin = this._map.getPixelOrigin(), bounds = L.bounds(this._transform(this._projBounds.min, zoom)._subtract(pixelOrigin), this._transform(this._projBounds.max, zoom)._subtract(pixelOrigin)), size = bounds.getSize(), image = this._image;
+            L.DomUtil.setPosition(image, bounds.min);
+            image.style.width = size.x + 'px';
+            image.style.height = size.y + 'px';
+        },
+        _projectedToNewLayerPoint: function (point, newZoom, newCenter) {
+            var topLeft = this._map._getNewTopLeftPoint(newCenter, newZoom).add(this._map._getMapPanePos());
+            return this._transform(point, newZoom)._subtract(topLeft);
+        },
+        _transform: function (p, zoom) {
+            var crs = this._map.options.crs, transformation = crs.transformation, scale = crs.scale(zoom);
+            return transformation.transform(p, scale);
+        }
+    });
+    L.Proj.imageOverlay = function (url, bounds, options) {
+        return new L.Proj.ImageOverlay(url, bounds, options);
+    };
+    if (typeof L.CRS !== 'undefined') {
+        L.CRS.proj4js = function () {
+            return function (code, def, transformation, options) {
+                options = options || {};
+                if (transformation) {
+                    options.transformation = transformation;
+                }
+                return new L.Proj.CRS(code, def, options);
+            };
+        }();
+    }
+    return L.Proj;
+});
+!function (root, factory) {
+    if (true) {
+        proj4leaflet10x = function (leaflet, proj4) {
+            return typeof factory === 'function' ? factory(leaflet, proj4) : factory;
+        }(leaflet, proj4);
+    } else if (typeof module === 'object' && typeof module.exports === 'object') {
+        L = leaflet;
+        proj4 = proj4;
+        module.exports = factory(L, proj4);
+    } else {
+        if (typeof root.L === 'undefined' || typeof root.proj4 === 'undefined')
+            throw 'Leaflet and proj4 must be loaded first';
+        factory(root.L, root.proj4);
+    }
+}(this, function (L, proj4) {
+    L.Proj = {};
+    L.Proj._isProj4Obj = function (a) {
+        return typeof a.inverse !== 'undefined' && typeof a.forward !== 'undefined';
+    };
+    L.Proj.Projection = L.Class.extend({
+        initialize: function (code, def, bounds) {
+            var isP4 = L.Proj._isProj4Obj(code);
+            this._proj = isP4 ? code : this._projFromCodeDef(code, def);
+            this.bounds = isP4 ? def : bounds;
+        },
+        project: function (latlng) {
+            var point = this._proj.forward([
+                latlng.lng,
+                latlng.lat
+            ]);
+            return new L.Point(point[0], point[1]);
+        },
+        unproject: function (point, unbounded) {
+            var point2 = this._proj.inverse([
+                point.x,
+                point.y
+            ]);
+            return new L.LatLng(point2[1], point2[0], unbounded);
+        },
+        _projFromCodeDef: function (code, def) {
+            if (def) {
+                proj4.defs(code, def);
+            } else if (proj4.defs[code] === undefined) {
+                var urn = code.split(':');
+                if (urn.length > 3) {
+                    code = urn[urn.length - 3] + ':' + urn[urn.length - 1];
+                }
+                if (proj4.defs[code] === undefined) {
+                    throw 'No projection definition for code ' + code;
+                }
+            }
+            return proj4(code);
+        }
+    });
+    L.Proj.CRS = L.Class.extend({
+        includes: L.CRS,
+        options: { transformation: new L.Transformation(1, 0, -1, 0) },
+        initialize: function (a, b, c) {
+            var code, proj, def, options;
+            if (L.Proj._isProj4Obj(a)) {
+                proj = a;
+                code = proj.srsCode;
+                options = b || {};
+                this.projection = new L.Proj.Projection(proj, options.bounds);
+            } else {
+                code = a;
+                def = b;
+                options = c || {};
+                this.projection = new L.Proj.Projection(code, def, options.bounds);
+            }
+            L.Util.setOptions(this, options);
+            this.code = code;
+            this.transformation = this.options.transformation;
+            if (this.options.origin) {
+                this.transformation = new L.Transformation(1, -this.options.origin[0], -1, this.options.origin[1]);
+            }
+            if (this.options.scales) {
+                this._scales = this.options.scales;
+            } else if (this.options.resolutions) {
+                this._scales = [];
+                for (var i = this.options.resolutions.length - 1; i >= 0; i--) {
+                    if (this.options.resolutions[i]) {
+                        this._scales[i] = 1 / this.options.resolutions[i];
+                    }
+                }
+            }
+            this.infinite = !this.options.bounds;
+        },
+        scale: function (zoom) {
+            var iZoom = Math.floor(zoom), baseScale, nextScale, scaleDiff, zDiff;
+            if (zoom === iZoom) {
+                return this._scales[zoom];
+            } else {
+                baseScale = this._scales[iZoom];
+                nextScale = this._scales[iZoom + 1];
+                scaleDiff = nextScale - baseScale;
+                zDiff = zoom - iZoom;
+                return baseScale + scaleDiff * zDiff;
+            }
+        },
+        zoom: function (scale) {
+            var downScale = this._closestElement(this._scales, scale), downZoom = this._scales.indexOf(downScale), nextZoom, scaleDiff;
+            if (scale === downScale) {
+                return downZoom;
+            }
+            nextZoom = downZoom + 1;
+            scaleDiff = this._scales[nextZoom] - downScale;
+            return (scale - downScale) / scaleDiff + downZoom;
+        },
+        _closestElement: function (array, element) {
+            var low;
+            for (var i = array.length; i--;) {
+                if (array[i] <= element && (low === undefined || low < array[i])) {
+                    low = array[i];
+                }
+            }
+            return low;
+        }
+    });
+    L.Proj.GeoJSON = L.GeoJSON.extend({
+        initialize: function (geojson, options) {
+            if (geojson.crs && geojson.crs.type === 'name') {
+                var crs = new L.Proj.CRS(geojson.crs.properties.name);
+                options = options || {};
+                options.coordsToLatLng = function (coords) {
+                    var point = L.point(coords[0], coords[1]);
+                    return crs.projection.unproject(point);
+                };
+            }
+            L.GeoJSON.prototype.initialize.call(this, geojson, options);
+        }
+    });
+    L.Proj.geoJson = function (geojson, options) {
+        return new L.Proj.GeoJSON(geojson, options);
+    };
+    return L.Proj;
+});
+LeafletCRSProj4Leaflet = function (require, L, proj4) {
+    return {
+        load: function () {
+            console.log('loading lib proj4leaflet ...');
+            var proj4leaflet = null;
+            if (L.version.lastIndexOf('0.7', 0) === 0) {
+                proj4leaflet = proj4leaflet07x;
+                console.log('loaded version for leaflet 0.7.7 ...');
+            } else if (L.version.lastIndexOf('1.0', 0) === 0) {
+                proj4leaflet = proj4leaflet10x;
+                console.log('loaded version for leaflet 1.0.0 ...');
+            } else {
+                console.log('version leaflet incompatible !');
+                return;
+            }
+            L.Proj = proj4leaflet;
+            return L.Proj;
+        }
+    };
+}({}, leaflet, proj4);
+CommonUtilsRegister = function (proj4) {
+    var Register = {
+        isLoaded: false,
+        get: function (name) {
+            if (name === '' || name === null || typeof name === 'undefined') {
+                return;
+            }
+            var s = name.split(':');
+            if (s.length !== 2) {
+                return;
+            }
+            var register = s[0];
+            var code = s[1];
+            if (!this.hasOwnProperty(register)) {
+                return;
+            }
+            if (!this[register].hasOwnProperty(code)) {
+                return;
+            }
+            return this[register][code];
+        },
+        load: function () {
+            if (!this.isLoaded) {
+                var registers = [
+                    'IGNF',
+                    'EPSG',
+                    'CRS'
+                ];
+                for (var i = 0; i < registers.length; i++) {
+                    var register = registers[i];
+                    var codes = this[register];
+                    for (var code in codes) {
+                        if (codes.hasOwnProperty(code)) {
+                            var name = register + ':' + code;
+                            proj4.defs(name, this.get(name));
+                        }
+                    }
+                }
+                this.isLoaded = true;
+            }
+        },
+        EPSG: {
+            4149: '+title=CH1903 +proj=longlat +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +no_defs ',
+            4150: '+title=CH1903plus +proj=longlat +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +no_defs ',
+            4151: '+title=CHTRF95 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4171: '+title=RGF93 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4230: '+title=ED50 +proj=longlat +ellps=intl +no_defs ',
+            4235: '+title=Guyane Francaise +proj=longlat +ellps=intl +no_defs ',
+            4258: '+title=ETRS89 +proj=longlat +ellps=GRS80 +no_defs ',
+            4275: '+title=NTF +proj=longlat +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +no_defs ',
+            4322: '+title=WGS 72 +proj=longlat +ellps=WGS72 +no_defs ',
+            4326: '+title=WGS 84 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ',
+            4467: '+proj=utm +zone=21 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            4470: '+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4471: '+proj=utm +zone=38 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            4474: '+proj=utm +zone=38 +south +ellps=intl +towgs84=-382,-59,-262,0,0,0,0 +units=m +no_defs ',
+            4558: '+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4559: '+proj=utm +zone=20 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            4621: '+title=Fort Marigot +proj=longlat +ellps=intl +towgs84=137,248,-430,0,0,0,0 +no_defs ',
+            4622: '+title=Guadeloupe 1948 +proj=longlat +ellps=intl +no_defs ',
+            4623: '+title=CSG67 +proj=longlat +ellps=intl +towgs84=-186,230,110,0,0,0,0 +no_defs ',
+            4624: '+title=RGFG95 +proj=longlat +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +no_defs ',
+            4625: '+title=Martinique 1938 +proj=longlat +ellps=intl +no_defs ',
+            4626: '+title=Reunion 1947 +proj=longlat +ellps=intl +no_defs ',
+            4627: '+title=RGR92 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4628: '+title=Tahiti 52 +proj=longlat +ellps=intl +towgs84=162,117,154,0,0,0,0 +no_defs ',
+            4629: '+title=Tahaa 54 +proj=longlat +ellps=intl +no_defs ',
+            4630: '+title=IGN72 Nuku Hiva +proj=longlat +ellps=intl +no_defs ',
+            4632: '+title=Combani 1950 +proj=longlat +ellps=intl +towgs84=-382,-59,-262,0,0,0,0 +no_defs ',
+            4633: '+title=IGN56 Lifou +proj=longlat +ellps=intl +no_defs ',
+            4634: '+title=IGN72 Grand Terre +proj=longlat +ellps=intl +no_defs ',
+            4637: '+title=Perroud 1950 +proj=longlat +ellps=intl +towgs84=325,154,172,0,0,0,0 +no_defs ',
+            4638: '+title=Saint Pierre et Miquelon 1950 +proj=longlat +ellps=clrk66 +towgs84=30,430,368,0,0,0,0 +no_defs ',
+            4640: '+title=RRAF 1991 +proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4641: '+title=IGN53 Mare +proj=longlat +ellps=intl +no_defs ',
+            4645: '+title=RGNC 1991 +proj=longlat +ellps=intl +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4687: '+proj=longlat +ellps=GRS80 +no_defs ',
+            4662: '+title=IGN72 Grande Terre +proj=longlat +ellps=intl +no_defs ',
+            4689: '+title=IGN63 Hiva Oa +proj=longlat +ellps=intl +no_defs ',
+            4690: '+title=Tahiti 79 +proj=longlat +ellps=intl +no_defs ',
+            4691: '+title=Moorea 87 +proj=longlat +ellps=intl +towgs84=215.525,149.593,176.229,-3.2624,-1.692,-1.1571,10.4773 +no_defs ',
+            4692: '+title=Maupiti 83 +proj=longlat +ellps=intl +towgs84=217.037,86.959,23.956,0,0,0,0 +no_defs ',
+            4698: '+title=IGN 1962 Kerguelen +proj=longlat +ellps=intl +towgs84=145,-187,103,0,0,0,0 +no_defs ',
+            4749: '+title=RGNC91-93 +proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs ',
+            4750: '+title=ST87 Ouvea +proj=longlat +ellps=WGS84 +towgs84=-56.263,16.136,-22.856,0,0,0,0 +no_defs ',
+            4807: '+title=NTF (Paris) +proj=longlat +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +no_defs ',
+            2056: '+title=CH1903+ / LV95 +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs ',
+            2154: '+title=RGF93 / Lambert-93 +proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            2213: '+title=ETRS89 / TM 30 NE +proj=tmerc +lat_0=0 +lon_0=30 +k=0.9996 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs ',
+            2969: '+title=Fort Marigot / UTM zone 20N +proj=utm +zone=20 +ellps=intl +towgs84=137,248,-430,0,0,0,0 +units=m +no_defs ',
+            2970: '+title=Guadeloupe 1948 / UTM zone 20N +proj=utm +zone=20 +ellps=intl +units=m +no_defs ',
+            2971: '+title=CSG67 / UTM zone 22N +proj=utm +zone=22 +ellps=intl +towgs84=-186,230,110,0,0,0,0 +units=m +no_defs ',
+            2972: '+title=RGFG95 / UTM zone 22N +proj=utm +zone=22 +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +units=m +no_defs ',
+            2973: '+title=Martinique 1938 / UTM zone 20N +proj=utm +zone=20 +ellps=intl +units=m +no_defs ',
+            2975: '+title=RGR92 / UTM zone 40S +proj=utm +zone=40 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            2976: '+title=Tahiti 52 / UTM zone 6S +proj=utm +zone=6 +south +ellps=intl +towgs84=162,117,154,0,0,0,0 +units=m +no_defs ',
+            2977: '+title=Tahaa 54 / UTM zone 5S +proj=utm +zone=5 +south +ellps=intl +units=m +no_defs ',
+            2978: '+title=IGN72 Nuku Hiva / UTM zone 7S +proj=utm +zone=7 +south +ellps=intl +units=m +no_defs ',
+            2980: '+title=Combani 1950 / UTM zone 38S +proj=utm +zone=38 +south +ellps=intl +towgs84=-382,-59,-262,0,0,0,0 +units=m +no_defs ',
+            2981: '+title=IGN56 Lifou / UTM zone 58S +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ',
+            2982: '+title=IGN72 Grand Terre / UTM zone 58S (deprecated) +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ',
+            2984: '+title=RGNC 1991 / Lambert New Caledonia (deprecated) +proj=lcc +lat_1=-20.66666666666667 +lat_2=-22.33333333333333 +lat_0=-21.5 +lon_0=166 +x_0=400000 +y_0=300000 +ellps=intl +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            2986: '+title=Terre Adelie 1950 +proj=stere +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +lat_0=-90.000000000 +lon_0=140.000000000 +lat_ts=-67.000000000 +k=0.96027295 +x_0=300000.000 +y_0=-2299363.482 +units=m +no_defs',
+            2987: '+title=Saint Pierre et Miquelon 1950 / UTM zone 21N +proj=utm +zone=21 +ellps=clrk66 +towgs84=30,430,368,0,0,0,0 +units=m +no_defs ',
+            2989: '+title=RRAF 1991 / UTM zone 20N +proj=utm +zone=20 +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            2990: '+title=Reunion 1947 / TM Reunion (deprecated) +proj=tmerc +lat_0=-21.11666666666667 +lon_0=55.53333333333333 +k=1 +x_0=50000 +y_0=160000 +ellps=intl +units=m +no_defs ',
+            2995: '+title=IGN53 Mare / UTM zone 58S +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ',
+            3038: '+proj=utm +zone=26 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3039: '+proj=utm +zone=27 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3040: '+proj=utm +zone=28 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3041: '+proj=utm +zone=29 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3045: '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3046: '+proj=utm +zone=34 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3047: '+proj=utm +zone=35 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3048: '+proj=utm +zone=36 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3049: '+proj=utm +zone=37 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3050: '+proj=utm +zone=38 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3051: '+proj=utm +zone=39 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3034: '+title=ETRS89 / ETRS-LCC +proj=lcc +lat_1=35 +lat_2=65 +lat_0=52 +lon_0=10 +x_0=4000000 +y_0=2800000 +ellps=GRS80 +units=m +no_defs ',
+            3035: '+title=ETRS89 / ETRS-LAEA +proj=laea +lat_0=52 +lon_0=10 +x_0=4321000 +y_0=3210000 +ellps=GRS80 +units=m +no_defs ',
+            3042: '+title=ETRS89 / ETRS-TM30 +proj=utm +zone=30 +ellps=GRS80 +units=m +no_defs ',
+            3043: '+title=ETRS89 / ETRS-TM31 +proj=utm +zone=31 +ellps=GRS80 +units=m +no_defs ',
+            3044: '+title=ETRS89 / ETRS-TM32 +proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs ',
+            25828: '+proj=utm +zone=28 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            25829: '+proj=utm +zone=29 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            25833: '+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            25834: '+proj=utm +zone=34 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            25835: '+proj=utm +zone=35 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            25836: '+proj=utm +zone=36 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            25837: '+proj=utm +zone=37 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            25838: '+proj=utm +zone=38 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3060: '+title=IGN72 Grande Terre / UTM zone 58S +proj=utm +zone=58 +south +ellps=intl +units=m +no_defs ',
+            3163: '+title=RGNC91-93 / Lambert New Caledonia +proj=lcc +lat_1=-20.66666666666667 +lat_2=-22.33333333333333 +lat_0=-21.5 +lon_0=166 +x_0=400000 +y_0=300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3164: '+title=ST87 Ouvea / UTM zone 58S +proj=utm +zone=58 +south +ellps=WGS84 +towgs84=-56.263,16.136,-22.856,0,0,0,0 +units=m +no_defs ',
+            3165: '+title=NEA74 Noumea / Noumea Lambert +proj=lcc +lat_1=-22.24469175 +lat_2=-22.29469175 +lat_0=-22.26969175 +lon_0=166.44242575 +x_0=0.66 +y_0=1.02 +ellps=intl +units=m +no_defs ',
+            3166: '+title=NEA74 Noumea / Noumea Lambert 2 +proj=lcc +lat_1=-22.24472222222222 +lat_2=-22.29472222222222 +lat_0=-22.26972222222222 +lon_0=166.4425 +x_0=8.313000000000001 +y_0=-2.354 +ellps=intl +units=m +no_defs ',
+            3169: '+title=RGNC91-93 / UTM zone 57S +proj=utm +zone=57 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3170: '+title=RGNC91-93 / UTM zone 58S +proj=utm +zone=58 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3171: '+title=RGNC91-93 / UTM zone 59S +proj=utm +zone=59 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs ',
+            3172: '+title=IGN53 Mare / UTM zone 59S +proj=utm +zone=59 +south +ellps=intl +units=m +no_defs ',
+            3296: '+title=RGPF / UTM zone 5S +proj=utm +zone=5 +south +ellps=GRS80 +units=m +no_defs ',
+            3297: '+title=RGPF / UTM zone 6S +proj=utm +zone=6 +south +ellps=GRS80 +units=m +no_defs ',
+            3298: '+title=RGPF / UTM zone 7S +proj=utm +zone=7 +south +ellps=GRS80 +units=m +no_defs ',
+            3299: '+title=RGPF / UTM zone 8S +proj=utm +zone=8 +south +ellps=GRS80 +units=m +no_defs ',
+            3302: '+title=IGN63 Hiva Oa / UTM zone 7S +proj=utm +zone=7 +south +ellps=intl +units=m +no_defs ',
+            3303: '+title=Fatu Iva 72 / UTM zone 7S +proj=utm +zone=7 +south +ellps=intl +towgs84=347.103,1078.12,2623.92,-33.8875,70.6773,-9.3943,186.074 +units=m +no_defs ',
+            3304: '+title=Tahiti 79 / UTM zone 6S +proj=utm +zone=6 +south +ellps=intl +units=m +no_defs ',
+            3305: '+title=Moorea 87 / UTM zone 6S +proj=utm +zone=6 +south +ellps=intl +towgs84=215.525,149.593,176.229,-3.2624,-1.692,-1.1571,10.4773 +units=m +no_defs ',
+            3306: '+title=Maupiti 83 / UTM zone 5S +proj=utm +zone=5 +south +ellps=intl +towgs84=217.037,86.959,23.956,0,0,0,0 +units=m +no_defs ',
+            3312: '+title=CSG67 / UTM zone 21N +proj=utm +zone=21 +ellps=intl +towgs84=-186,230,110,0,0,0,0 +units=m +no_defs ',
+            3313: '+title=RGFG95 / UTM zone 21N +proj=utm +zone=21 +ellps=GRS80 +towgs84=2,2,-2,0,0,0,0 +units=m +no_defs ',
+            3336: '+title=IGN 1962 Kerguelen / UTM zone 42S +proj=utm +zone=42 +south +ellps=intl +towgs84=145,-187,103,0,0,0,0 +units=m +no_defs ',
+            3395: '+title=WGS 84 / World Mercator +proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            3727: '+title=Reunion 1947 / TM Reunion +proj=tmerc +lat_0=-21.11666666666667 +lon_0=55.53333333333333 +k=1 +x_0=160000 +y_0=50000 +ellps=intl +units=m +no_defs ',
+            21781: '+title=CH1903 / LV03 +proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +x_0=600000 +y_0=200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs ',
+            25830: '+title=ETRS89 / UTM zone 30N +proj=utm +zone=30 +ellps=GRS80 +units=m +no_defs ',
+            25831: '+title=ETRS89 / UTM zone 31N +proj=utm +zone=31 +ellps=GRS80 +units=m +no_defs ',
+            25832: '+title=ETRS89 / UTM zone 32N +proj=utm +zone=32 +ellps=GRS80 +units=m +no_defs ',
+            27561: '+title=NTF (Paris) / Lambert Nord France +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27562: '+title=NTF (Paris) / Lambert Centre France +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27563: '+title=NTF (Paris) / Lambert Sud France +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27564: '+title=NTF (Paris) / Lambert Corse +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27571: '+title=NTF (Paris) / Lambert zone I +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=1200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27572: '+title=NTF (Paris) / Lambert zone II +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27573: '+title=NTF (Paris) / Lambert zone III +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=3200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27574: '+title=NTF (Paris) / Lambert zone IV +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=4185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27581: '+title=NTF (Paris) / France I (deprecated) +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=1200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27582: '+title=NTF (Paris) / France II (deprecated) +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27583: '+title=NTF (Paris) / France III (deprecated) +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=3200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27584: '+title=NTF (Paris) / France IV (deprecated) +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=4185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27591: '+title=NTF (Paris) / Nord France (deprecated) +proj=lcc +lat_1=49.50000000000001 +lat_0=49.50000000000001 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27592: '+title=NTF (Paris) / Centre France (deprecated) +proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27593: '+title=NTF (Paris) / Sud France (deprecated) +proj=lcc +lat_1=44.10000000000001 +lat_0=44.10000000000001 +lon_0=0 +k_0=0.9998774990000001 +x_0=600000 +y_0=200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            27594: '+title=NTF (Paris) / Corse (deprecated) +proj=lcc +lat_1=42.16500000000001 +lat_0=42.16500000000001 +lon_0=0 +k_0=0.9999447100000001 +x_0=234.358 +y_0=185861.369 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs ',
+            32601: '+proj=utm +zone=1 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32602: '+proj=utm +zone=2 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32603: '+proj=utm +zone=3 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32604: '+proj=utm +zone=4 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32605: '+proj=utm +zone=5 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32606: '+proj=utm +zone=6 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32607: '+proj=utm +zone=7 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32608: '+proj=utm +zone=8 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32609: '+proj=utm +zone=9 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32610: '+proj=utm +zone=10 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32611: '+proj=utm +zone=11 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32612: '+proj=utm +zone=12 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32613: '+proj=utm +zone=13 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32614: '+proj=utm +zone=14 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32615: '+proj=utm +zone=15 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32616: '+proj=utm +zone=16 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32617: '+proj=utm +zone=17 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32618: '+proj=utm +zone=18 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32619: '+proj=utm +zone=19 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32620: '+proj=utm +zone=20 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32621: '+proj=utm +zone=21 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32622: '+proj=utm +zone=22 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32623: '+proj=utm +zone=23 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32624: '+proj=utm +zone=24 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32625: '+proj=utm +zone=25 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32626: '+proj=utm +zone=26 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32627: '+proj=utm +zone=27 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32628: '+proj=utm +zone=28 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32629: '+proj=utm +zone=29 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32630: '+proj=utm +zone=30 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32631: '+proj=utm +zone=31 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32632: '+proj=utm +zone=32 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32633: '+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32634: '+proj=utm +zone=34 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32635: '+proj=utm +zone=35 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32636: '+proj=utm +zone=36 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32637: '+proj=utm +zone=37 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32638: '+proj=utm +zone=38 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32639: '+proj=utm +zone=39 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32640: '+proj=utm +zone=40 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32641: '+proj=utm +zone=41 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32642: '+proj=utm +zone=42 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32643: '+proj=utm +zone=43 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32644: '+proj=utm +zone=44 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32645: '+proj=utm +zone=45 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32646: '+proj=utm +zone=46 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32647: '+proj=utm +zone=47 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32648: '+proj=utm +zone=48 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32649: '+proj=utm +zone=49 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32650: '+proj=utm +zone=50 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32651: '+proj=utm +zone=51 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32652: '+proj=utm +zone=52 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32653: '+proj=utm +zone=53 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32654: '+proj=utm +zone=54 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32655: '+proj=utm +zone=55 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32656: '+proj=utm +zone=56 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32657: '+proj=utm +zone=57 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32658: '+proj=utm +zone=58 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32659: '+proj=utm +zone=59 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32660: '+proj=utm +zone=60 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32661: '+proj=stere +lat_0=90 +lat_ts=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32662: '+title=WGS 84 / Plate Carree +proj=eqc +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32701: '+proj=utm +zone=1 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32702: '+proj=utm +zone=2 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32703: '+proj=utm +zone=3 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32704: '+proj=utm +zone=4 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32705: '+proj=utm +zone=5 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32706: '+proj=utm +zone=6 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32707: '+proj=utm +zone=7 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32708: '+proj=utm +zone=8 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32709: '+proj=utm +zone=9 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32710: '+proj=utm +zone=10 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32711: '+proj=utm +zone=11 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32712: '+proj=utm +zone=12 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32713: '+proj=utm +zone=13 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32714: '+proj=utm +zone=14 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32715: '+proj=utm +zone=15 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32716: '+proj=utm +zone=16 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32717: '+proj=utm +zone=17 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32718: '+proj=utm +zone=18 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32719: '+proj=utm +zone=19 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32720: '+proj=utm +zone=20 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32721: '+proj=utm +zone=21 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32722: '+proj=utm +zone=22 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32723: '+proj=utm +zone=23 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32724: '+proj=utm +zone=24 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32725: '+proj=utm +zone=25 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32726: '+proj=utm +zone=26 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32727: '+proj=utm +zone=27 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32728: '+proj=utm +zone=28 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32729: '+proj=utm +zone=29 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32730: '+proj=utm +zone=30 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32731: '+proj=utm +zone=31 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32732: '+proj=utm +zone=32 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32733: '+proj=utm +zone=33 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32734: '+proj=utm +zone=34 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32735: '+proj=utm +zone=35 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32736: '+proj=utm +zone=36 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32737: '+proj=utm +zone=37 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32738: '+proj=utm +zone=38 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32739: '+proj=utm +zone=39 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32740: '+proj=utm +zone=40 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32741: '+proj=utm +zone=41 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32742: '+proj=utm +zone=42 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32743: '+proj=utm +zone=43 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32744: '+proj=utm +zone=44 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32745: '+proj=utm +zone=45 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32746: '+proj=utm +zone=46 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32747: '+proj=utm +zone=47 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32748: '+proj=utm +zone=48 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32749: '+proj=utm +zone=49 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32750: '+proj=utm +zone=50 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32751: '+proj=utm +zone=51 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32752: '+proj=utm +zone=52 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32753: '+proj=utm +zone=53 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32754: '+proj=utm +zone=54 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32755: '+proj=utm +zone=55 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32756: '+proj=utm +zone=56 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32757: '+proj=utm +zone=57 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32758: '+proj=utm +zone=58 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32759: '+proj=utm +zone=59 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32760: '+proj=utm +zone=60 +south +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            32761: '+proj=stere +lat_0=-90 +lat_ts=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 +ellps=WGS84 +datum=WGS84 +units=m +no_defs ',
+            310024802: '+title=Geoportail - France metropolitaine +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=46.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310915814: '+title=Geoportail - Antilles francaises +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310486805: '+title=Geoportail - Guyane +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=4.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310700806: '+title=Geoportail - Reunion et dependances +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-21.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310702807: '+title=Geoportail - Mayotte +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-12.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310706808: '+title=Geoportail - Saint-Pierre et Miquelon +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=47.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310547809: '+title=Geoportail - Nouvelle-Caledonie +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-22.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310642810: '+title=Geoportail - Wallis et Futuna +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.000000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-14.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310032811: '+title=Geoportail - Polynesie francaise +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310642812: '+title=Geoportail - Kerguelen +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-49.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310642801: '+title=Geoportail - Crozet +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-46.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310642813: '+title=Geoportail - Amsterdam et Saint-Paul +proj=eqc +nadgrids=null +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-38.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            310642901: '+title=Geoportail - Monde +proj=mill +towgs84=0.0000,0.0000,0.0000,0.0000,0.0000,0.0000,0.000000 +a=6378137.0000 +rf=298.2572221010000 +lon_0=0.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            5489: '+title=RGAF09 geographiques (dms) +proj=longlat +nadgrids=@null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137 +rf=298.257222101 +units=m +no_defs',
+            5490: '+title=RGAF09 UTM Nord Fuseau 20 +proj=tmerc +nadgrids=@null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137 +rf=298.257222101 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs'
+        },
+        CRS: { 84: '+title=WGS 84 longitude-latitude +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ' },
+        IGNF: {
+            AMST63: '+title=Amsterdam 1963 +proj=geocent +towgs84=109.753,-528.133,-362.244,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            CROZ63: '+title=Crozet 1963 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            CSG67: '+title=Guyane CSG67 +proj=geocent +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            ED50: '+title=ED50 +proj=geocent +towgs84=-84.0000,-97.0000,-117.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            ETRS89: '+title=Systeme de reference terrestre Europeen (1989) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            GUAD48: '+title=Guadeloupe Ste Anne +proj=geocent +towgs84=-472.2900,-5.6300,-304.1200,0.4362,-0.8374,0.2563,1.898400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            GUADFM49: '+title=Guadeloupe Fort Marigot +proj=geocent +towgs84=136.5960,248.1480,-429.7890 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            IGN63: '+title=IGN 1963 (Hiva Oa, Tahuata, Mohotani) +proj=geocent +towgs84=410.7210,55.0490,80.7460,-2.5779,-2.3514,-0.6664,17.331100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            IGN72: '+title=IGN 1972 Grande-Terre / Ile des Pins +proj=geocent +towgs84=-11.6400,-348.6000,291.6800 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            KERG62CAR: '+title=Kerguelen - K0 +proj=geocent +towgs84=144.8990,-186.7700,100.9230 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            MART38: '+title=Martinique Fort-Desaix +proj=geocent +towgs84=126.9260,547.9390,130.4090,-2.7867,5.1612,-0.8584,13.822650 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            MAYO50: '+title=Mayotte Combani +proj=geocent +towgs84=-599.9280,-275.5520,-195.6650,-0.0835,-0.4715,0.0602,49.281400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            MOOREA87: '+title=Moorea 1987 +proj=geocent +towgs84=215.9820,149.5930,176.2290,3.2624,1.6920,1.1571,10.477300 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            NTF: '+title=Nouvelle Triangulation Francaise +proj=geocent +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +units=m +no_defs',
+            NUKU72: '+title=IGN 1972 Nuku Hiva +proj=geocent +towgs84=165.7320,216.7200,180.5050,-0.6434,-0.4512,-0.0791,7.420400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            REUN47: '+title=Reunion 1947 +proj=geocent +towgs84=789.5240,-626.4860,-89.9040,0.6006,76.7946,-10.5788,-32.324100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            RGF93: '+title=Reseau geodesique francais 1993 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGFG95: '+title=Reseau geodesique francais de Guyane 1995 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGM04: '+title=RGM04 (Reseau Geodesique de Mayotte 2004) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGNC: '+title=Reseau Geodesique de Nouvelle-Caledonie +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGPF: '+title=RGPF (Reseau Geodesique de Polynesie Francaise) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGR92: '+title=Reseau geodesique Reunion 1992 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGSPM06: '+title=Reseau Geodesique Saint-Pierre-et-Miquelon (2006) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGTAAF07: '+title=Reseau Geodesique des TAAF (2007) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RRAF91: '+title=RRAF 1991 (Reseau de Reference des Antilles Francaises) +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            STPL69: '+title=Saint-Paul 1969 +proj=geocent +towgs84=225.571,-346.608,-46.567,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            STPM50: '+title=St Pierre et Miquelon 1950 +proj=geocent +towgs84=-95.5930,573.7630,173.4420,-0.9602,1.2510,-1.3918,42.626500 +a=6378206.4000 +rf=294.9786982000000 +units=m +no_defs',
+            TAHAA: '+title=Raiatea - Tahaa 51-54 (Tahaa, Base Terme Est) +proj=geocent +towgs84=72.4380,345.9180,79.4860,-1.6045,-0.8823,-0.5565,1.374600 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            TAHI79: '+title=IGN79 (Tahiti) Iles de la Societe +proj=geocent +towgs84=221.5250,152.9480,176.7680,2.3847,1.3896,0.8770,11.474100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            TERA50: '+title=Pointe Geologie - Perroud 1950 +proj=geocent +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            WALL78: '+title=Wallis-Uvea 1978 (MOP78) +proj=geocent +towgs84=253.0000,-133.0000,-127.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            WGS72: '+title=World Geodetic System 1972 +proj=geocent +towgs84=0.0000,12.0000,6.0000 +a=6378135.0000 +rf=298.2600000000000 +units=m +no_defs',
+            WGS84: '+title=World Geodetic System 1984 +proj=geocent +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            AMST63GEO: '+title=Amsterdam 1963 +proj=longlat +towgs84=109.753,-528.133,-362.244,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            CROZ63GEO: '+title=Crozet 1963 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            CSG67GEO: '+title=Guyane CSG67 +proj=longlat +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            ED50G: '+title=ED50 +proj=longlat +towgs84=-84.0000,-97.0000,-117.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            GUAD48GEO: '+title=Guadeloupe Ste Anne +proj=longlat +towgs84=-472.2900,-5.6300,-304.1200,0.4362,-0.8374,0.2563,1.898400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            GUADFM49GEO: '+title=Guadeloupe Fort Marigot +proj=longlat +towgs84=136.5960,248.1480,-429.7890 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            IGN63GEO: '+title=IGN 1963 (Hiva Oa, Tahuata, Mohotani) +proj=longlat +towgs84=410.7210,55.0490,80.7460,-2.5779,-2.3514,-0.6664,17.331100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            IGN72GEO: '+title=IGN 1972 Grande-Terre / Ile des Pins +proj=longlat +towgs84=-11.6400,-348.6000,291.6800 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            KERG62GEO: '+title=Kerguelen - K0 +proj=longlat +towgs84=144.8990,-186.7700,100.9230 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            MART38GEO: '+title=Martinique Fort-Desaix +proj=longlat +towgs84=126.9260,547.9390,130.4090,-2.7867,5.1612,-0.8584,13.822650 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            MAYO50GEO: '+title=Mayotte Combani +proj=longlat +towgs84=-599.9280,-275.5520,-195.6650,-0.0835,-0.4715,0.0602,49.281400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            MOOREA87GEO: '+title=Moorea 1987 +proj=longlat +towgs84=215.9820,149.5930,176.2290,3.2624,1.6920,1.1571,10.477300 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            NTFG: '+title=Nouvelle Triangulation Francaise Greenwich degres sexagesimaux +proj=longlat +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +units=m +no_defs',
+            NTFP: '+title=Nouvelle Triangulation Francaise Paris grades +proj=longlat +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +units=m +no_defs',
+            NUKU72GEO: '+title=IGN 1972 Nuku Hiva +proj=longlat +towgs84=165.7320,216.7200,180.5050,-0.6434,-0.4512,-0.0791,7.420400 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            REUN47GEO: '+title=Reunion 1947 +proj=longlat +towgs84=789.5240,-626.4860,-89.9040,0.6006,76.7946,-10.5788,-32.324100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            RGF93G: '+title=Reseau geodesique francais 1993 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGFG95GEO: '+title=Reseau geodesique francais de Guyane 1995 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGM04GEO: '+title=RGM04 (Reseau Geodesique de Mayotte 2004) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGNCGEO: '+title=Reseau Geodesique de Nouvelle-Caledonie +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGPFGEO: '+title=RGPF (Reseau Geodesique de Polynesie Francaise) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGR92GEO: '+title=Reseau geodesique de la Reunion 1992 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGSPM06GEO: '+title=Saint-Pierre-et-Miquelon (2006) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            RGTAAF07G: '+title=Reseau Geodesique des TAAF (2007) (dms) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            STPL69GEO: '+title=Saint-Paul 1969 +proj=longlat +towgs84=225.571,-346.608,-46.567,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            STPM50GEO: '+title=St Pierre et Miquelon 1950  +proj=longlat +towgs84=-95.5930,573.7630,173.4420,-0.9602,1.2510,-1.3918,42.626500 +a=6378206.4000 +rf=294.9786982000000 +units=m +no_defs',
+            TAHAAGEO: '+title=Raiatea - Tahaa 51-54 (Tahaa, Base Terme Est) +proj=longlat +towgs84=72.4380,345.9180,79.4860,-1.6045,-0.8823,-0.5565,1.374600 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            TAHI79GEO: '+title=IGN79 (Tahiti) Iles de la Societe +proj=longlat +towgs84=221.5250,152.9480,176.7680,2.3847,1.3896,0.8770,11.474100 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            TERA50G: '+title=Pointe Geologie - Perroud 1950 +proj=longlat +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            WALL78GEO: '+title=Wallis - Uvea 1978 (MOP78) +proj=longlat +towgs84=253.0000,-133.0000,-127.0000 +a=6378388.0000 +rf=297.0000000000000 +units=m +no_defs',
+            WGS72G: '+title=WGS72 +proj=longlat +towgs84=0.0000,12.0000,6.0000 +a=6378135.0000 +rf=298.2600000000000 +units=m +no_defs',
+            WGS84G: '+title=World Geodetic System 1984 +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            WGS84RRAFGEO: '+title=Reseau de reference des Antilles francaises (1988-1991) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            XGEO: '+title=Systeme CIO-BIH +proj=longlat +towgs84=0.0000,0.0000,0.5000,0.0000,0.0000,0.0140,-0.100000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            AMST63UTM43S: '+title=Amsterdam 1963 UTM fuseau 43 Sud +proj=tmerc +towgs84=109.753,-528.133,-362.244,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=75.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            CROZ63UTM39S: '+title=Crozet 1963 +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            CSG67UTM21: '+title=Guyane CSG67 UTM fuseau 21 +proj=tmerc +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            CSG67UTM22: '+title=Guyane CSG67 UTM fuseau 22 +proj=tmerc +towgs84=-193.0660,236.9930,105.4470,0.4814,-0.8074,0.1276,1.564900 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALANF: '+title=Geoportail - Antilles francaises +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALASP: '+title=Geoportail - Amsterdam et Saint-Paul +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-38.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALCRZ: '+title=Geoportail - Crozet +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-46.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALFXX: '+title=Geoportail - France metropolitaine +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=46.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALGUF: '+title=Geoportail - Guyane +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=4.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALKER: '+title=Geoportail - Kerguelen +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-49.500000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALMYT: '+title=Geoportail - Mayotte +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-12.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALNCL: '+title=Geoportail - Nouvelle-Caledonie +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-22.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALPYF: '+title=Geoportail - Polynesie francaise +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-15.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALREU: '+title=Geoportail - Reunion et dependances +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-21.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALSPM: '+title=Geoportail - Saint-Pierre et Miquelon +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=47.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GEOPORTALWLF: '+title=Geoportail - Wallis et Futuna +proj=eqc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=0.000000000 +lat_ts=-14.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            GUAD48UTM20: '+title=Guadeloupe Ste Anne +proj=tmerc +towgs84=-472.2900,-5.6300,-304.1200,0.4362,-0.8374,0.2563,1.898400 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            GUADFM49U20: '+title=Guadeloupe Fort Marigot  +proj=tmerc +towgs84=136.5960,248.1480,-429.7890 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            IGN63UTM7S: '+title=IGN 1963 - Hiva Oa, Tahuata, Mohotani - UTM fuseau 7 Sud +proj=tmerc +towgs84=410.7210,55.0490,80.7460,-2.5779,-2.3514,-0.6664,17.331100 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-141.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            IGN72UTM58S: '+title=IGN 1972 - UTM fuseau 58 Sud +proj=tmerc +towgs84=-11.6400,-348.6000,291.6800 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=165.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            KERG62UTM42S: '+title=Kerguelen 1962 +proj=tmerc +towgs84=144.8990,-186.7700,100.9230 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=69.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            LAMB1: '+title=Lambert I +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=49.500000000 +lon_0=0.000000000 +k_0=0.99987734 +lat_1=49.500000000 +x_0=600000.000 +y_0=200000.000 +units=m +no_defs',
+            LAMB1C: '+title=Lambert I Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=49.500000000 +lon_0=0.000000000 +k_0=0.99987734 +lat_1=49.500000000 +x_0=600000.000 +y_0=1200000.000 +units=m +no_defs',
+            LAMB2: '+title=Lambert II +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=46.800000000 +lon_0=0.000000000 +k_0=0.99987742 +lat_1=46.800000000 +x_0=600000.000 +y_0=200000.000 +units=m +no_defs',
+            LAMB2C: '+title=Lambert II Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=46.800000000 +lon_0=0.000000000 +k_0=0.99987742 +lat_1=46.800000000 +x_0=600000.000 +y_0=2200000.000 +units=m +no_defs',
+            LAMB3: '+title=Lambert III +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=44.100000000 +lon_0=0.000000000 +k_0=0.99987750 +lat_1=44.100000000 +x_0=600000.000 +y_0=200000.000 +units=m +no_defs',
+            LAMB3C: '+title=Lambert III Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=44.100000000 +lon_0=0.000000000 +k_0=0.99987750 +lat_1=44.100000000 +x_0=600000.000 +y_0=3200000.000 +units=m +no_defs',
+            LAMB4: '+title=Lambert IV +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=42.165000000 +lon_0=0.000000000 +k_0=0.99994471 +lat_1=42.165000000 +x_0=234.358 +y_0=185861.369 +units=m +no_defs',
+            LAMB4C: '+title=Lambert IV Carto +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=42.165000000 +lon_0=0.000000000 +k_0=0.99994471 +lat_1=42.165000000 +x_0=234.358 +y_0=4185861.369 +units=m +no_defs',
+            LAMB93: '+title=Lambert 93 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=46.500000000 +lon_0=3.000000000 +lat_1=44.000000000 +lat_2=49.000000000 +x_0=700000.000 +y_0=6600000.000 +units=m +no_defs',
+            RGF93CC42: '+title=Lambert conique conforme Zone 1 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=42.000000000 +lon_0=3.000000000 +lat_1=41.200000000 +lat_2=42.800000000 +x_0=1700000.000 +y_0=1200000.000 +units=m +no_defs',
+            RGF93CC43: '+title=Lambert conique conforme Zone 2 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=43.000000000 +lon_0=3.000000000 +lat_1=42.200000000 +lat_2=43.800000000 +x_0=1700000.000 +y_0=2200000.000 +units=m +no_defs',
+            RGF93CC44: '+title=Lambert conique conforme Zone 3 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=44.000000000 +lon_0=3.000000000 +lat_1=43.200000000 +lat_2=44.800000000 +x_0=1700000.000 +y_0=3200000.000 +units=m +no_defs',
+            RGF93CC45: '+title=Lambert conique conforme Zone 4 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=45.000000000 +lon_0=3.000000000 +lat_1=44.200000000 +lat_2=45.800000000 +x_0=1700000.000 +y_0=4200000.000 +units=m +no_defs',
+            RGF93CC46: '+title=Lambert conique conforme Zone 5 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=46.000000000 +lon_0=3.000000000 +lat_1=45.200000000 +lat_2=46.800000000 +x_0=1700000.000 +y_0=5200000.000 +units=m +no_defs',
+            RGF93CC47: '+title=Lambert conique conforme Zone 6 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=47.000000000 +lon_0=3.000000000 +lat_1=46.200000000 +lat_2=47.800000000 +x_0=1700000.000 +y_0=6200000.000 +units=m +no_defs',
+            RGF93CC48: '+title=Lambert conique conforme Zone 7 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=48.000000000 +lon_0=3.000000000 +lat_1=47.200000000 +lat_2=48.800000000 +x_0=1700000.000 +y_0=7200000.000 +units=m +no_defs',
+            RGF93CC49: '+title=Lambert conique conforme Zone 8 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=49.000000000 +lon_0=3.000000000 +lat_1=48.200000000 +lat_2=49.800000000 +x_0=1700000.000 +y_0=8200000.000 +units=m +no_defs',
+            RGF93CC50: '+title=Lambert conique conforme Zone 9 +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=50.000000000 +lon_0=3.000000000 +lat_1=49.200000000 +lat_2=50.800000000 +x_0=1700000.000 +y_0=9200000.000 +units=m +no_defs',
+            LAMBE: '+title=Lambert II etendu +proj=lcc +nadgrids=ntf_r93.gsb,null +wktext +towgs84=-168.0000,-60.0000,320.0000 +a=6378249.2000 +rf=293.4660210000000 +pm=2.337229167 +lat_0=46.800000000 +lon_0=0.000000000 +k_0=0.99987742 +lat_1=46.800000000 +x_0=600000.000 +y_0=2200000.000 +units=m +no_defs',
+            MART38UTM20: '+title=Martinique Fort-Desaix +proj=tmerc +towgs84=126.9260,547.9390,130.4090,-2.7867,5.1612,-0.8584,13.822650 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            MAYO50UTM38S: '+title=Mayotte Combani +proj=tmerc +towgs84=-599.9280,-275.5520,-195.6650,-0.0835,-0.4715,0.0602,49.281400 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=45.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            MILLER: '+title=Geoportail - Monde +proj=mill +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lon_0=0.000000000 +x_0=0.000 +y_0=0.000 +units=m +no_defs',
+            MOOREA87U6S: '+title=Moorea 1987 - UTM fuseau 6 Sud +proj=tmerc +towgs84=215.9820,149.5930,176.2290,3.2624,1.6920,1.1571,10.477300 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            NUKU72U7S: '+title=IGN 1972 Nuku Hiva - UTM fuseau 7 Sud +proj=tmerc +towgs84=165.7320,216.7200,180.5050,-0.6434,-0.4512,-0.0791,7.420400 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-141.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            REUN47GAUSSL: '+title=Reunion Gauss Laborde +proj=gstmerc +towgs84=789.5240,-626.4860,-89.9040,0.6006,76.7946,-10.5788,-32.324100 +a=6378388.0000 +rf=297.0000000000000 +lat_0=-21.116666667 +lon_0=55.533333333 +k_0=1.00000000 +x_0=160000.000 +y_0=50000.000 +units=m +no_defs',
+            RGM04UTM38S: '+title=UTM fuseau 38 Sud (Reseau Geodesique de Mayotte 2004) +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=45.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGNCUTM57S: '+title=Reseau Geodesique de Nouvelle-Caledonie - UTM fuseau 57 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=159.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGNCUTM58S: '+title=Reseau Geodesique de Nouvelle-Caledonie - UTM fuseau 58 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=165.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGNCUTM59S: '+title=Reseau Geodesique de Nouvelle-Caledonie - UTM fuseau 59 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=171.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGPFUTM5S: '+title=RGPF - UTM fuseau 5 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-153.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGPFUTM6S: '+title=RGPF - UTM fuseau 6 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGPFUTM7S: '+title=RGPF - UTM fuseau 7 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-141.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGR92UTM40S: '+title=RGR92 UTM fuseau 40 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            RGSPM06U21: '+title=Saint-Pierre-et-Miquelon (2006) UTM Fuseau 21 Nord +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            STPL69UTM43S: '+title=Saint-Paul 1969 UTM fuseau 43 Sud +proj=tmerc +towgs84=225.571,-346.608,-46.567,0,0,0,0 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=75.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            STPM50UTM21: '+title=St Pierre et Miquelon 1950 +proj=tmerc +towgs84=-95.5930,573.7630,173.4420,-0.9602,1.2510,-1.3918,42.626500 +a=6378206.4000 +rf=294.9786982000000 +lat_0=0.000000000 +lon_0=-57.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            TAHAAUTM05S: '+title=Tahaa 1951 +proj=tmerc +towgs84=72.4380,345.9180,79.4860,-1.6045,-0.8823,-0.5565,1.374600 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-153.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            TAHI51UTM06S: '+title=Tahiti-Terme Nord UTM fuseau 6 Sud +proj=tmerc +towgs84=162.0000,117.0000,154.0000 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            TAHI79UTM6S: '+title=Tahiti 1979 +proj=tmerc +towgs84=221.5250,152.9480,176.7680,2.3847,1.3896,0.8770,11.474100 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-147.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            TERA50STEREO: '+title=Terre Adelie 1950 +proj=stere +towgs84=324.9120,153.2820,172.0260 +a=6378388.0000 +rf=297.0000000000000 +lat_0=-90.000000000 +lon_0=140.000000000 +lat_ts=-67 +k=0.96027295 +x_0=300000.000 +y_0=-2299363.482 +units=m +no_defs',
+            UTM01SW84: '+title=World Geodetic System 1984 UTM fuseau 01 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-177.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            UTM20W84GUAD: '+title=World Geodetic System 1984 UTM fuseau 20 Nord-Guadeloupe +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM20W84MART: '+title=World Geodetic System 1984 UTM fuseau 20 Nord-Martinique +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-63.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM22RGFG95: '+title=RGFG95 UTM fuseau 22 Nord-Guyane +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM39SW84: '+title=World Geodetic System 1984 UTM fuseau 39 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=51.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            UTM42SW84: '+title=World Geodetic System 1984 UTM fuseau 42 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=69.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            UTM43SW84: '+title=World Geodetic System 1984 UTM fuseau 43 Sud +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=75.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            WALL78UTM1S: '+title=Wallis-Uvea 1978 (MOP78) UTM 1 SUD +proj=tmerc +towgs84=253.0000,-133.0000,-127.0000 +a=6378388.0000 +rf=297.0000000000000 +lat_0=0.000000000 +lon_0=-177.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=10000000.000 +units=m +no_defs',
+            ETRS89GEO: '+title=ETRS89 geographiques (dms) +proj=longlat +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +units=m +no_defs',
+            ETRS89LAEA: '+title=ETRS89 Lambert Azimutal Equal Area +proj=laea +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=52.000000000 +lon_0=10.000000000 +x_0=4321000.000 +y_0=3210000.000 +units=m +no_defs',
+            ETRS89LCC: '+title=ETRS89 Lambert Conformal Conic +proj=lcc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=52.000000000 +lon_0=9.999999995 +lat_1=35.000000000 +lat_2=65.000000000 +x_0=4000000.000 +y_0=2800000.000 +units=m +no_defs',
+            UTM26ETRS89: '+title=Europe - de 30d a 24d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-27.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM27ETRS89: '+title=Europe - de 24d a 18d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-21.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM28ETRS89: '+title=Europe - de 18d a 12d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-15.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM29ETRS89: '+title=Europe - de 12d a 6d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-9.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM30ETRS89: '+title=Europe - de -6d a 0d Ouest +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=-3.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM31ETRS89: '+title=Europe - de 0d a 6d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=3.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM32ETRS89: '+title=Europe - de 6d a 12d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=9.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM33ETRS89: '+title=Europe - de 12d a 18d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=15.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM34ETRS89: '+title=Europe - de 18d a 24d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=21.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM35ETRS89: '+title=Europe - de 24d a 30d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=27.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM36ETRS89: '+title=Europe - de 30d a 36d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=33.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM37ETRS89: '+title=Europe - de 36d a 42d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=39.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs',
+            UTM38ETRS89: '+title=Europe - de 42d a 48d Est +proj=tmerc +nadgrids=null +wktext +towgs84=0.0000,0.0000,0.0000 +a=6378137.0000 +rf=298.2572221010000 +lat_0=0.000000000 +lon_0=45.000000000 +k_0=0.99960000 +x_0=500000.000 +y_0=0.000 +units=m +no_defs'
+        }
+    };
+    return Register;
+}(proj4);
+LeafletCRSEPSG2154 = function (Config, Register, L) {
+    var EPSG2154 = {
+        instance: null,
+        build: function () {
+            if (!this.instance) {
+                var crs = new L.Proj.CRS('EPSG:2154', Register.get('EPSG:2154'), {
+                    resolutions: this._getResolutions(),
+                    origin: this._getOrigin()
+                });
+                this.instance = crs;
+            }
+            return this.instance;
+        },
+        _getResolutions: function () {
+            var resolutions = [];
+            if (Config.isConfigLoaded()) {
+                var o = Config.getTileMatrix('LAMB93');
+                resolutions = o.nativeResolutions;
+            }
+            if (resolutions.length) {
+                return resolutions;
+            }
+            return [
+                104579.22454989408,
+                52277.53235379051,
+                26135.487078595408,
+                13066.891381800004,
+                6533.228604113456,
+                3266.5595244626675,
+                1633.2660045974187,
+                816.6295549860224,
+                408.31391467683596,
+                204.15674151090204,
+                102.07831678324082,
+                51.0391448966112,
+                25.519569074269395,
+                12.759783693647506,
+                6.379891635966491,
+                3.18994576530532,
+                1.5949728694977277,
+                0.7974864315474559,
+                0.398743214900604,
+                0.19937160727567999,
+                0.099685803696052,
+                0.049842901818919996
+            ];
+        },
+        _getOrigin: function () {
+            return [
+                0,
+                12000000
+            ];
+        }
+    };
+    return EPSG2154;
+}(CommonUtilsConfig, CommonUtilsRegister, leaflet);
+LeafletCRSEPSG27572 = function (Config, Register, L) {
+    var EPSG27572 = {
+        instance: null,
+        build: function () {
+            if (!this.instance) {
+                var crs = new L.Proj.CRS('EPSG:27572', Register.get('EPSG:27572'), {
+                    resolutions: this._getResolutions(),
+                    origin: this._getOrigin()
+                });
+                this.instance = crs;
+            }
+            return this.instance;
+        },
+        _getResolutions: function () {
+            var resolutions = [];
+            if (Config.isConfigLoaded()) {
+                var o = Config.getTileMatrix('LAMB2E');
+                if (o && Object.keys(o)) {
+                    resolutions = o.nativeResolutions;
+                }
+            }
+            if (resolutions.length) {
+                return resolutions;
+            }
+            return [
+                104579.22454989408,
+                52277.53235379051,
+                26135.487078595408,
+                13066.891381800004,
+                6533.228604113456,
+                3266.5595244626675,
+                1633.2660045974187,
+                816.6295549860224,
+                408.31391467683596,
+                204.15674151090204,
+                102.07831678324082,
+                51.0391448966112,
+                25.519569074269395,
+                12.759783693647506,
+                6.379891635966491,
+                3.18994576530532,
+                1.5949728694977277,
+                0.7974864315474559,
+                0.398743214900604,
+                0.19937160727567999,
+                0.099685803696052,
+                0.049842901818919996
+            ];
+        },
+        _getOrigin: function () {
+            return [
+                0,
+                12000000
+            ];
+        }
+    };
+    return EPSG27572;
+}(CommonUtilsConfig, CommonUtilsRegister, leaflet);
+LeafletCRSEPSG4326 = function (Config, Register, L) {
+    var EPSG4326 = {
+        instance: null,
+        build: function () {
+            if (!this.instance) {
+                var crs = new L.Proj.CRS('EPSG:4326', Register.get('EPSG:4326'), {
+                    resolutions: this._getResolutions(),
+                    origin: [
+                        -180,
+                        90
+                    ]
+                });
+                this.instance = crs;
+            }
+            return this.instance;
+        },
+        _getResolutions: function () {
+            var resolutions = [];
+            if (Config.isConfigLoaded()) {
+                resolutions = Config.getResolutions();
+            }
+            if (resolutions.length) {
+                return resolutions;
+            }
+            return [
+                1.40625,
+                0.703125,
+                0.3515625,
+                0.17578125,
+                0.087890625,
+                0.0439453125,
+                0.02197265625,
+                0.010986328125,
+                0.0054931640625,
+                0.00274658203125,
+                0.001373291015625,
+                0.0006866455078125,
+                0.00034332275390625,
+                0.000171661376953126,
+                0.0000858306884765628,
+                0.0000429153442382813,
+                0.0000214576721191407,
+                0.0000107288360595703,
+                0.00000536441802978517,
+                0.00000268220901489259,
+                0.0000013411045074463,
+                6.70552253723145e-7,
+                3.3527612686157e-7
+            ];
+        },
+        _getOrigin: function () {
+        }
+    };
+    return EPSG4326;
+}(CommonUtilsConfig, CommonUtilsRegister, leaflet);
+LeafletCRSCRS = function (Proj4, Register, Epsg2154, Epsg27572, Epsg4326) {
+    (function () {
+        Proj4.load();
+        Register.load();
+    }());
+    var CRS = {
+        EPSG2154: function () {
+            return Epsg2154.build();
+        },
+        EPSG27572: function () {
+            return Epsg27572.build();
+        },
+        EPSG4326: function () {
+            return Epsg4326.build();
+        }
+    };
+    return CRS;
+}(LeafletCRSProj4Leaflet, CommonUtilsRegister, LeafletCRSEPSG2154, LeafletCRSEPSG27572, LeafletCRSEPSG4326);
+LeafletControlsMousePosition = function (L, woodman, Gp, RightManagement, ID, MousePositionDOM, PositionFormater, CRS) {
+    var MousePosition = L.Control.extend({
+        includes: MousePositionDOM,
+        options: {
+            position: 'bottomleft',
+            collapsed: true,
+            units: [],
+            systems: [],
+            displayAltitude: true,
+            displayCoordinates: true,
+            altitude: {
+                triggerDelay: 200,
+                responseDelay: 500,
+                noDataValue: -99999,
+                noDataValueTolerance: 90000,
+                serviceOptions: {}
+            }
+        },
+        initialize: function (options) {
+            L.Util.extend(this.options, options);
+            this._uid = ID.generate();
+            this._projectionSystems = [];
+            this._initProjectionSystems();
+            this._projectionUnits = {};
+            this._initProjectionUnits();
+            this._isDesktop = this._detectSupport();
+            if (this.options.altitude.triggerDelay < 100) {
+                this.options.altitude.triggerDelay = 100;
+            }
+            this._timer = this.options.altitude.triggerDelay;
+            this._currentProjectionSystems = this._projectionSystems[0];
+            this._projectionSystemsContainer = null;
+            this._currentProjectionType = this._projectionSystems[0].type;
+            this._currentProjectionUnits = this._projectionUnits[this._currentProjectionType][0].code;
+            this._projectionUnitsContainer = null;
+            this._showMousePositionContainer = null;
+            if (!this.options.displayAltitude && !this.options.displayCoordinates) {
+                this.options.displayCoordinates = true;
+            }
+            this._noRightManagement = false;
+            if (this.options.displayAltitude) {
+                this._checkRightsManagement();
+            }
+            L.Util.setOptions(this, this.options);
+        },
+        onAdd: function (map) {
+            var container = this._container = this._initLayout();
+            if (!this.options.collapsed) {
+                if (this._isDesktop) {
+                    map.on('mousemove', this.onMouseMove, this);
+                } else {
+                    map.on('move', this.onMapMove, this);
+                }
+            }
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            L.DomEvent.addListener(container, 'mousemove', L.DomEvent.stopPropagation).addListener(container, 'mousemove', L.DomEvent.preventDefault);
+            return container;
+        },
+        onRemove: function (map) {
+            map.off('mousemove', this.onMouseMove);
+        },
+        _initProjectionSystems: function () {
+            var projectionSystemsByDefault = [
+                {
+                    label: 'Géographique',
+                    crs: L.CRS.Simple,
+                    type: 'Geographical'
+                },
+                {
+                    label: 'Web Mercator',
+                    crs: L.CRS.EPSG3395,
+                    type: 'Metric'
+                },
+                {
+                    label: 'Lambert 93',
+                    crs: CRS.EPSG2154,
+                    type: 'Metric',
+                    geoBBox: {
+                        left: -9.86,
+                        bottom: 41.15,
+                        right: 10.38,
+                        top: 51.56
+                    }
+                },
+                {
+                    label: 'Lambert II étendu',
+                    crs: CRS.EPSG27572,
+                    type: 'Metric',
+                    geoBBox: {
+                        left: -4.87,
+                        bottom: 42.33,
+                        right: 8.23,
+                        top: 51.14
+                    }
+                }
+            ];
+            var systems = this.options.systems;
+            for (var i = 0; i < systems.length; i++) {
+                var sys = systems[i];
+                if (!sys.label) {
+                    continue;
+                }
+                if (!sys.crs) {
+                    continue;
+                }
+                if (!sys.type) {
+                    sys.type = 'Metric';
+                }
+                this._projectionSystems.push(systems[i]);
+                var found = false;
+                for (var j = 0; j < projectionSystemsByDefault.length; j++) {
+                    var obj = projectionSystemsByDefault[j];
+                    if (sys.crs === obj.crs) {
+                        found = true;
+                    }
+                }
+                if (!found) {
+                }
+            }
+            if (this._projectionSystems.length === 0) {
+                this._projectionSystems = projectionSystemsByDefault;
+            }
+            for (var k = 0; k < this._projectionSystems.length; ++k) {
+                this._projectionSystems[k].code = k;
+            }
+        },
+        _initProjectionUnits: function () {
+            var projectionUnitsByDefault = {
+                Geographical: [
+                    {
+                        code: 'DEC',
+                        label: 'degrés décimaux',
+                        convert: this._displayDEC
+                    },
+                    {
+                        code: 'DMS',
+                        label: 'degrés sexagésimaux',
+                        convert: this._displayDMS
+                    },
+                    {
+                        code: 'RAD',
+                        label: 'radians',
+                        convert: this._displayRAD
+                    },
+                    {
+                        code: 'GON',
+                        label: 'grades',
+                        convert: this._displayGON
+                    }
+                ],
+                Metric: [
+                    {
+                        code: 'M',
+                        label: 'mètres',
+                        convert: this._displayMeter
+                    },
+                    {
+                        code: 'KM',
+                        label: 'kilomètres',
+                        convert: this._displayKMeter
+                    }
+                ]
+            };
+            var units = this.options.units;
+            for (var type in projectionUnitsByDefault) {
+                if (projectionUnitsByDefault.hasOwnProperty(type)) {
+                    var found = false;
+                    for (var j = 0; j < projectionUnitsByDefault[type].length; j++) {
+                        var obj = projectionUnitsByDefault[type][j];
+                        for (var i = 0; i < units.length; i++) {
+                            var unit = units[i];
+                            if (obj.code === unit) {
+                                found = true;
+                                if (!this._projectionUnits[type]) {
+                                    this._projectionUnits[type] = [];
+                                }
+                                this._projectionUnits[type].push(obj);
+                            }
+                        }
+                    }
+                    if (!found) {
+                        this._projectionUnits[type] = projectionUnitsByDefault[type];
+                    }
+                }
+            }
+            if (Object.keys(this._projectionUnits).length === 0) {
+                this._projectionUnits = projectionUnitsByDefault;
+            }
+        },
+        _checkRightsManagement: function () {
+            var rightManagement = RightManagement.check({
+                key: this.options.apiKey,
+                resources: ['SERVICE_CALCUL_ALTIMETRIQUE_RSC'],
+                services: ['Elevation']
+            });
+            if (!rightManagement) {
+                this._noRightManagement = true;
+            }
+            if (!this.options.apiKey) {
+                this.options.apiKey = rightManagement.key;
+            }
+        },
+        _detectSupport: function () {
+            var isDesktop = true;
+            var userAgent = window.navigator.userAgent.toLowerCase();
+            if (userAgent.indexOf('iphone') !== -1 || userAgent.indexOf('ipod') !== -1 || userAgent.indexOf('ipad') !== -1 || userAgent.indexOf('android') !== -1 || userAgent.indexOf('mobile') !== -1 || userAgent.indexOf('blackberry') !== -1 || userAgent.indexOf('tablet') !== -1 || userAgent.indexOf('phone') !== -1 || userAgent.indexOf('touch') !== -1) {
+                isDesktop = false;
+            }
+            if (userAgent.indexOf('msie') !== -1 || userAgent.indexOf('trident') !== -1) {
+                isDesktop = true;
+            }
+            return isDesktop;
+        },
+        _initLayout: function () {
+            var container = this._createMainContainerElement();
+            var inputShow = this._showMousePositionContainer = this._createShowMousePositionElement();
+            container.appendChild(inputShow);
+            if (!this.options.collapsed) {
+                inputShow.checked = true;
+            }
+            var picto = this._createShowMousePositionPictoElement(this._isDesktop);
+            container.appendChild(picto);
+            var panel = this._createMousePositionPanelElement(this.options.displayAltitude, this.options.displayCoordinates);
+            var settings = this._createMousePositionSettingsElement();
+            var systems = this._projectionSystemsContainer = this._createMousePositionSettingsSystemsElement(this._projectionSystems);
+            var units = this._projectionUnitsContainer = this._createMousePositionSettingsUnitsElement(this._projectionUnits[this._currentProjectionType]);
+            settings.appendChild(systems);
+            settings.appendChild(units);
+            panel.appendChild(settings);
+            container.appendChild(panel);
+            var center = this._createMapCenter();
+            var map = this._map;
+            map.getContainer().appendChild(center);
+            return container;
+        },
+        _setElevationPanel: function (active) {
+            var div = null;
+            if (!active) {
+                div = L.DomUtil.get(this._addUID('GPmousePositionAltitude'));
+                div.style.display = 'none';
+            }
+            if (active && this._noRightManagement) {
+                div = L.DomUtil.get(this._addUID('GPmousePositionAlt'));
+                div.innerHTML = 'no right !';
+            }
+        },
+        _setCoordinatePanel: function (active) {
+            if (!active) {
+                var div = L.DomUtil.get(this._addUID('GPmousePositionCoordinate'));
+                div.style.display = 'none';
+            }
+        },
+        _setSettingsPanel: function (active) {
+            if (!active) {
+                var divPicto = L.DomUtil.get('GPshowMousePositionSettingsPicto');
+                var divPanel = L.DomUtil.get(this._addUID('GPmousePositionSettings'));
+                divPicto.style.display = 'none';
+                divPanel.style.display = 'none';
+            }
+        },
+        _setTypeUnitsPanel: function (type) {
+            var container = this._projectionUnitsContainer;
+            while (container.firstChild) {
+                container.removeChild(container.firstChild);
+            }
+            var units = this._projectionUnits[type];
+            for (var j = 0; j < units.length; j++) {
+                var obj = units[j];
+                var option = document.createElement('option');
+                option.value = obj.code ? obj.code : j;
+                option.text = obj.label || j;
+                container.appendChild(option);
+            }
+            this._currentProjectionType = type;
+            this._currentProjectionUnits = this._projectionUnits[type][0].code;
+        },
+        _displayDEC: function (oLatLng) {
+            var coordinate = {};
+            coordinate.lat = PositionFormater.roundToDecimal(oLatLng.lat, 6);
+            coordinate.lng = PositionFormater.roundToDecimal(oLatLng.lng, 6);
+            return coordinate;
+        },
+        _displayDMS: function (oLatLng) {
+            var coordinate = {};
+            coordinate.lat = PositionFormater.decimalLatToDMS(oLatLng.lat);
+            coordinate.lng = PositionFormater.decimalLongToDMS(oLatLng.lng);
+            return coordinate;
+        },
+        _displayRAD: function (oLatLng) {
+            var coordinate = {};
+            coordinate.lat = PositionFormater.decimalToRadian(oLatLng.lat);
+            coordinate.lng = PositionFormater.decimalToRadian(oLatLng.lng);
+            return coordinate;
+        },
+        _displayGON: function (oLatLng) {
+            var coordinate = {};
+            coordinate.lat = PositionFormater.decimalToGrade(oLatLng.lat);
+            coordinate.lng = PositionFormater.decimalToGrade(oLatLng.lng);
+            return coordinate;
+        },
+        _displayMeter: function (oXY) {
+            var coordinate = {};
+            coordinate.x = L.Util.formatNum(oXY.x, 2);
+            coordinate.y = L.Util.formatNum(oXY.y, 2);
+            coordinate.unit = 'm';
+            return coordinate;
+        },
+        _displayKMeter: function (oXY) {
+            var coordinate = {};
+            coordinate.x = L.Util.formatNum(oXY.x / 1000, 2);
+            coordinate.y = L.Util.formatNum(oXY.y / 1000, 2);
+            coordinate.unit = 'km';
+            return coordinate;
+        },
+        _project: function (oLatLng, crs) {
+            if (typeof crs === 'function') {
+                crs = crs();
+            }
+            if (typeof crs !== 'object') {
+                return;
+            }
+            if (crs === L.CRS.Simple) {
+                return oLatLng;
+            }
+            if (!crs.projection || typeof crs.projection !== 'object') {
+                return;
+            }
+            var oPoint = crs.projection.project(oLatLng);
+            if (this._currentProjectionType === 'Geographical') {
+                oPoint.lat = oPoint.y;
+                oPoint.lng = oPoint.x;
+            }
+            if (!oPoint || Object.keys(oPoint).length === 0) {
+            }
+            return oPoint;
+        },
+        _setCoordinate: function (oLatLng) {
+            var type = this._currentProjectionSystems.type;
+            var convert = null;
+            var units = this._projectionUnits[type];
+            for (var i = 0; i < units.length; i++) {
+                if (units[i].code === this._currentProjectionUnits) {
+                    convert = units[i].convert;
+                    break;
+                }
+            }
+            var coordinate = {};
+            var oSrs = this._currentProjectionSystems.crs;
+            if (!oSrs) {
+                return;
+            }
+            coordinate = convert(this._project(oLatLng, oSrs));
+            if (!coordinate || Object.keys(coordinate).lenght === 0) {
+                return;
+            }
+            this.GPdisplayCoords(coordinate);
+        },
+        _setElevation: function (oLatLng) {
+            var delay = this.options.altitude.responseDelay;
+            var noDataValue = this.options.altitude.noDataValue;
+            var noDataValueTolerance = this.options.altitude.noDataValueTolerance;
+            this.GPdisplayElevation(oLatLng, delay, noDataValue, noDataValueTolerance);
+        },
+        onMoveStopped: function (oLatLng) {
+            if (this._noRightManagement) {
+                return;
+            }
+            this._setElevation(oLatLng);
+        },
+        onMouseMove: function (e) {
+            var self = this;
+            var oLatLng = e.latlng;
+            this._setCoordinate(oLatLng);
+            clearTimeout(this._timer);
+            this._timer = setTimeout(function () {
+                self.onMoveStopped(oLatLng);
+            }, this.options.altitude.triggerDelay);
+        },
+        onMapMove: function () {
+            var self = this;
+            var map = this._map;
+            var oLatLng = map.getCenter();
+            this._setCoordinate(oLatLng);
+            clearTimeout(this._timer);
+            this._timer = setTimeout(function () {
+                self.onMoveStopped(oLatLng);
+            }, this.options.altitude.triggerDelay);
+        },
+        onRequestAltitude: function (coordinate, callback) {
+            if (!coordinate || Object.keys(coordinate).length === 0) {
+                return;
+            }
+            if (!this.options.displayAltitude) {
+                return;
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            var options = {};
+            L.Util.extend(options, this.options.altitude.serviceOptions);
+            L.Util.extend(options, {
+                zonly: true,
+                positions: [{
+                        lon: coordinate.lon || coordinate.lng,
+                        lat: coordinate.lat
+                    }]
+            });
+            L.Util.extend(options, {
+                scope: this,
+                onSuccess: function (results) {
+                    if (results && Object.keys(results)) {
+                        callback.call(this, results.elevations[0].z);
+                    }
+                },
+                onFailure: function (error) {
+                }
+            });
+            L.Util.extend(options, { apiKey: options.apiKey || this.options.apiKey });
+            Gp.Services.getAltitude(options);
+        },
+        onShowMousePositionClick: function (e) {
+            var map = this._map;
+            if (this._showMousePositionContainer.checked) {
+                this._isDesktop ? map.off('mousemove', this.onMouseMove, this) : map.off('move', this.onMapMove, this);
+            } else {
+                this._isDesktop ? map.on('mousemove', this.onMouseMove, this) : map.on('move', this.onMapMove, this);
+            }
+            this._setElevationPanel(this.options.displayAltitude);
+            this._setCoordinatePanel(this.options.displayCoordinates);
+            if (!this.options.displayCoordinates) {
+                this._setSettingsPanel(false);
+            }
+        },
+        onMousePositionProjectionSystemChange: function (e) {
+            var idx = e.target.selectedIndex;
+            var value = e.target.options[idx].value;
+            var label = e.target.options[idx].label;
+            this._setCurrentSystem(value);
+        },
+        _setCurrentSystem: function (systemCode) {
+            var type = null;
+            for (var i = 0; i < this._projectionSystems.length; ++i) {
+                if (this._projectionSystems[i].code == systemCode) {
+                    type = this._projectionSystems[i].type;
+                    break;
+                }
+            }
+            if (!type) {
+                return;
+            }
+            if (type !== this._currentProjectionType) {
+                this._setTypeUnitsPanel(type);
+            }
+            this._currentProjectionSystems = this._projectionSystems[Number(systemCode)];
+            if (!this._isDesktop) {
+                this.onMapMove();
+            }
+        },
+        onMousePositionProjectionSystemMouseOver: function (e) {
+            var map = this._map;
+            if (!map) {
+                return;
+            }
+            var systemList = document.getElementById(this._addUID('GPmousePositionProjectionSystem'));
+            systemList.innerHTML = '';
+            for (var j = 0; j < this._projectionSystems.length; j++) {
+                var proj = this._projectionSystems[j];
+                if (proj.geoBBox) {
+                    if (map.getBounds()._southWest.lng > proj.geoBBox.right || map.getBounds()._southWest.lat > proj.geoBBox.top || map.getBounds()._northEast.lng < proj.geoBBox.left || map.getBounds()._northEast.lat < proj.geoBBox.bottom) {
+                        if (proj === this._currentProjectionSystems) {
+                            var option = document.createElement('option');
+                            option.value = proj.code;
+                            option.text = proj.label || j;
+                            option.setAttribute('selected', 'selected');
+                            option.setAttribute('disabled', 'disabled');
+                            systemList.appendChild(option);
+                        }
+                        continue;
+                    }
+                }
+                var option = document.createElement('option');
+                option.value = proj.code;
+                option.text = proj.label || j;
+                if (proj === this._currentProjectionSystems) {
+                    option.setAttribute('selected', 'selected');
+                }
+                systemList.appendChild(option);
+            }
+        },
+        onMousePositionProjectionUnitsChange: function (e) {
+            var idx = e.target.selectedIndex;
+            var value = e.target.options[idx].value;
+            var label = e.target.options[idx].label;
+            this._currentProjectionUnits = value;
+            if (!this._isDesktop) {
+                this.onMapMove();
+            }
+        }
+    });
+    return MousePosition;
+}(leaflet, {}, gp, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, CommonControlsMousePositionDOM, LeafletControlsUtilsPositionFormater, LeafletCRSCRS);
+CommonControlsReverseGeocodingDOM = function () {
+    var ReverseGeocodingDOM = {
+        _addUID: function (id) {
+            return id + '-' + this._uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPreverseGeocoding');
+            container.className = 'GPwidget';
+            return container;
+        },
+        _createShowReverseGeocodingElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowReverseGeocoding');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowReverseGeocodingPictoElement: function () {
+            var self = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowReverseGeocodingPicto');
+            label.className = 'GPshowAdvancedToolPicto';
+            label.htmlFor = this._addUID('GPshowReverseGeocoding');
+            label.title = 'Ouvrir la recherche inverse';
+            if (label.addEventListener) {
+                label.addEventListener('click', function () {
+                    self.onShowReverseGeocodingClick();
+                });
+            } else if (label.attachEvent) {
+                label.attachEvent('onclick', function () {
+                    self.onShowReverseGeocodingClick();
+                });
+            }
+            var spanOpen = document.createElement('span');
+            spanOpen.id = this._addUID('GPshowReverseGeocodingOpen');
+            spanOpen.className = 'GPshowAdvancedToolOpen';
+            label.appendChild(spanOpen);
+            return label;
+        },
+        _createReverseGeocodingWaitingElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPreverseGeocodingCalcWaitingContainer');
+            div.className = 'GPreverseGeocodingCalcWaitingContainerHidden';
+            var p = document.createElement('p');
+            p.className = 'GPreverseGeocodingCalcWaiting';
+            p.innerHTML = 'Recherche en cours...';
+            div.appendChild(p);
+            return div;
+        },
+        _createReverseGeocodingResultsPanelElement: function () {
+            var resultsPanelDiv = document.createElement('div');
+            resultsPanelDiv.id = this._addUID('GPreverseGeocodingResultsPanel');
+            resultsPanelDiv.className = 'GPpanel GPreverseGeocodingComponentHidden';
+            return resultsPanelDiv;
+        },
+        _createReverseGeocodingResultsListElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPreverseGeocodingResultsList');
+            return container;
+        },
+        _createReverseGeocodingResultElement: function (locationDescription, id) {
+            var context = this;
+            var container = document.getElementById(this._addUID('GPreverseGeocodingResultsList'));
+            var div = document.createElement('div');
+            div.id = this._addUID('ReverseGeocodedLocation_' + id);
+            div.className = 'GPautoCompleteProposal';
+            div.innerHTML = locationDescription;
+            div.title = locationDescription;
+            if (div.addEventListener) {
+                div.addEventListener('mouseover', function (e) {
+                    context.onReverseGeocodingResultMouseOver(e);
+                });
+                div.addEventListener('mouseout', function (e) {
+                    context.onReverseGeocodingResultMouseOut(e);
+                });
+                div.addEventListener('click', function (e) {
+                    if (typeof context.onReverseGeocodingResultClick === 'function') {
+                        context.onReverseGeocodingResultClick(e);
+                    }
+                });
+            } else if (div.attachEvent) {
+                div.attachEvent('onmouseover', function (e) {
+                    context.onReverseGeocodingResultMouseOver(e);
+                });
+                div.attachEvent('onmouseout', function (e) {
+                    context.onReverseGeocodingResultMouseOut(e);
+                });
+                div.attachEvent('onclick', function (e) {
+                    if (typeof context.onReverseGeocodingResultClick === 'function') {
+                        context.onReverseGeocodingResultClick(e);
+                    }
+                });
+            }
+            container.appendChild(div);
+        },
+        _createReverseGeocodingPanelElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPreverseGeocodingPanel');
+            div.className = 'GPpanel';
+            return div;
+        },
+        _createReverseGeocodingPanelHeaderElement: function () {
+            var container = document.createElement('div');
+            container.className = 'GPpanelHeader';
+            return container;
+        },
+        _createReverseGeocodingPanelReturnPictoElement: function () {
+            var self = this;
+            var divNew = document.createElement('div');
+            divNew.id = this._addUID('GPreverseGeocodingReturnPicto');
+            divNew.title = 'Nouvelle recherche';
+            divNew.className = 'GPreverseGeocodingReturnPictoHidden';
+            if (divNew.addEventListener) {
+                divNew.addEventListener('click', function (e) {
+                    document.getElementById(self._addUID('GPreverseGeocodingResultsPanel')).className = 'GProuteComponentHidden';
+                    document.getElementById(self._addUID('GPreverseGeocodingForm')).className = '';
+                    document.getElementById(self._addUID('GPreverseGeocodingHeaderTitle')).innerHTML = 'Recherche inverse';
+                    document.getElementById(self._addUID('GPreverseGeocodingReturnPicto')).className = 'GPreverseGeocodingReturnPictoHidden';
+                    self.onGPreverseGeocodingReturnPictoClick(e);
+                });
+            } else if (divNew.attachEvent) {
+                divNew.attachEvent('onclick', function (e) {
+                    document.getElementById(self._addUID('GPreverseGeocodingResultsPanel')).className = 'GProuteComponentHidden';
+                    document.getElementById(self._addUID('GPreverseGeocodingForm')).className = '';
+                    document.getElementById(self._addUID('GPreverseGeocodingHeaderTitle')).innerHTML = 'Recherche inverse';
+                    document.getElementById(self._addUID('GPreverseGeocodingReturnPicto')).className = 'GPreverseGeocodingReturnPictoHidden';
+                    self.onGPreverseGeocodingReturnPictoClick(e);
+                });
+            }
+            return divNew;
+        },
+        _createReverseGeocodingPanelTitleElement: function () {
+            var div = document.createElement('div');
+            div.className = 'GPpanelTitle';
+            div.id = this._addUID('GPreverseGeocodingHeaderTitle');
+            div.innerHTML = 'Recherche inverse';
+            return div;
+        },
+        _createReverseGeocodingPanelCloseElement: function () {
+            var self = this;
+            var divClose = document.createElement('div');
+            divClose.id = this._addUID('GPreverseGeocodingPanelClose');
+            divClose.className = 'GPpanelClose';
+            divClose.title = 'Fermer le panneau';
+            if (divClose.addEventListener) {
+                divClose.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPshowReverseGeocodingPicto')).click();
+                }, false);
+            } else if (divClose.attachEvent) {
+                divClose.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPshowReverseGeocodingPicto')).click();
+                });
+            }
+            return divClose;
+        },
+        _createReverseGeocodingPanelFormElement: function () {
+            var self = this;
+            var form = document.createElement('form');
+            form.id = this._addUID('GPreverseGeocodingForm');
+            if (form.addEventListener) {
+                form.addEventListener('submit', function (e) {
+                    e.preventDefault();
+                    self.onReverseGeocodingSubmit();
+                });
+            } else if (form.attachEvent) {
+                form.attachEvent('onsubmit', function (e) {
+                    e.preventDefault();
+                    self.onReverseGeocodingSubmit();
+                });
+            }
+            return form;
+        },
+        _createReverseGeocodingFormModeChoiceGeocodingTypeElement: function (resources) {
+            var context = this;
+            var div = document.createElement('div');
+            div.className = 'GPflexInput';
+            var label = document.createElement('label');
+            label.className = 'GPreverseGeocodingCodeLabel';
+            label.innerHTML = 'Recherche par';
+            label.title = 'Recherche par';
+            div.appendChild(label);
+            var select = document.createElement('select');
+            select.className = 'GPreverseGeocodingCode';
+            if (select.addEventListener) {
+                select.addEventListener('change', function (e) {
+                    context.onReverseGeocodingTypeChange(e);
+                });
+            } else if (select.attachEvent) {
+                select.attachEvent('onchange', function (e) {
+                    context.onReverseGeocodingTypeChange(e);
+                });
+            }
+            if (!resources || !Array.isArray(resources)) {
+                resources = [
+                    'StreetAddress',
+                    'PositionOfInterest',
+                    'CadastralParcel'
+                ];
+            }
+            for (var i = 0; i < resources.length; i++) {
+                switch (resources[i]) {
+                case 'PositionOfInterest':
+                    var POIOption = document.createElement('option');
+                    POIOption.value = 'PositionOfInterest';
+                    POIOption.text = 'Lieux/toponymes';
+                    select.appendChild(POIOption);
+                    break;
+                case 'StreetAddress':
+                    var SAOption = document.createElement('option');
+                    SAOption.value = 'StreetAddress';
+                    SAOption.text = 'Adresses';
+                    select.appendChild(SAOption);
+                    break;
+                case 'CadastralParcel':
+                    var CPOption = document.createElement('option');
+                    CPOption.value = 'CadastralParcel';
+                    CPOption.text = 'Parcelles cadastrales';
+                    select.appendChild(CPOption);
+                    break;
+                case 'Administratif':
+                    var adminOption = document.createElement('option');
+                    adminOption.value = 'Administratif';
+                    adminOption.text = 'Unités administratives';
+                    select.appendChild(adminOption);
+                    break;
+                default:
+                    break;
+                }
+            }
+            div.appendChild(select);
+            return div;
+        },
+        _createReverseGeocodingFormModeChoiceGeocodingDelimitationElement: function (delimitations) {
+            var context = this;
+            var div = document.createElement('div');
+            div.className = 'GPflexInput';
+            var label = document.createElement('label');
+            label.className = 'GPreverseGeocodingCodeLabel';
+            label.innerHTML = 'Délimitation';
+            label.title = 'Délimitation';
+            div.appendChild(label);
+            var select = document.createElement('select');
+            select.className = 'GPreverseGeocodingCode';
+            if (select.addEventListener) {
+                select.addEventListener('change', function (e) {
+                    context.onReverseGeocodingDelimitationChange(e);
+                });
+            } else if (select.attachEvent) {
+                select.attachEvent('onchange', function (e) {
+                    context.onReverseGeocodingDelimitationChange(e);
+                });
+            }
+            if (!delimitations || !Array.isArray(delimitations)) {
+                delimitations = [
+                    'Point',
+                    'Circle',
+                    'Extent'
+                ];
+            }
+            for (var i = 0; i < delimitations.length; i++) {
+                switch (delimitations[i].toLowerCase()) {
+                case 'point':
+                    var pointOption = document.createElement('option');
+                    pointOption.value = 'point';
+                    pointOption.text = 'Pointer un lieu';
+                    select.appendChild(pointOption);
+                    break;
+                case 'circle':
+                    var circleOption = document.createElement('option');
+                    circleOption.value = 'circle';
+                    circleOption.text = 'Dessiner un cercle';
+                    select.appendChild(circleOption);
+                    break;
+                case 'extent':
+                    var extentOption = document.createElement('option');
+                    extentOption.value = 'extent';
+                    extentOption.text = 'Dessiner une emprise';
+                    select.appendChild(extentOption);
+                    break;
+                default:
+                    break;
+                }
+            }
+            div.appendChild(select);
+            return div;
+        },
+        _createReverseGeocodingSubmitFormElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPreverseGeocodingSubmit');
+            input.className = 'GPinputSubmit';
+            input.type = 'submit';
+            input.value = 'Rechercher';
+            return input;
+        }
+    };
+    return ReverseGeocodingDOM;
+}();
+LeafletControlsReverseGeocoding = function (L, P, woodman, Gp, RightManagement, ID, IconDefault, ReverseGeocodingDOM) {
+    var ReverseGeocoding = L.Control.extend({
+        includes: ReverseGeocodingDOM,
+        options: {
+            position: 'bottomleft',
+            collapsed: true,
+            resources: [
+                'StreetAddress',
+                'PositionOfInterest'
+            ],
+            delimitations: [
+                'Point',
+                'Circle',
+                'Extent'
+            ],
+            reverseGeocodeOptions: {}
+        },
+        initialize: function (options) {
+            L.Util.extend(this.options, options);
+            this._noRightManagement = false;
+            this._servicesRightManagement = {};
+            this._checkRightsManagement();
+            this._checkInputOptions();
+            this._uid = ID.generate();
+            this._currentGeocodingType = null;
+            this._initGeocodingType();
+            this._currentGeocodingDelimitation = null;
+            this._initGeocodingDelimitation();
+            this._showReverseGeocodingContainer = null;
+            this._panelHeaderContainer = null;
+            this._panelTitleContainer = null;
+            this._returnPictoContainer = null;
+            this._formContainer = null;
+            this._resultsContainer = null;
+            this._resultsListContainer = null;
+            this._waitingContainer = null;
+            this._inputFeaturesLayer = null;
+            this._inputResultsLayer = null;
+            this._lastIdLayer = 0;
+            this._currentIdLayer = 0;
+            this._currentFeature = null;
+            this._requestPosition = null;
+            this._requestCircleFilter = null;
+            this._requestBboxFilter = null;
+            this._waiting = false;
+            this._timer = null;
+            this._reverseGeocodingLocations = [];
+        },
+        onAdd: function (map) {
+            var container = this._container = this._initLayout();
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            if (map) {
+                if (!this.options.collapsed) {
+                    this._activateMapInteraction(map);
+                }
+            }
+            return container;
+        },
+        onRemove: function () {
+        },
+        _checkRightsManagement: function () {
+            var _resources = [];
+            var _key;
+            var _opts = null;
+            _key = this.options.reverseGeocodeOptions.apiKey;
+            _opts = this.options.reverseGeocodeOptions.filterOptions;
+            _resources = _opts ? _opts.type : [];
+            if (!_resources || _resources.length === 0) {
+                _resources = this.options.resources;
+            }
+            if (!_resources || _resources.length === 0) {
+                _resources = [
+                    'StreetAddress',
+                    'PositionOfInterest'
+                ];
+            }
+            var rightManagementGeocode = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _resources,
+                services: ['Geocode']
+            });
+            if (!rightManagementGeocode) {
+                this._noRightManagement = true;
+                return;
+            }
+            if (!this.options.apiKey) {
+                this.options.apiKey = rightManagementGeocode.key;
+            }
+            if (rightManagementGeocode) {
+                this._servicesRightManagement['Geocode'] = rightManagementGeocode['Geocode'];
+            }
+        },
+        _checkInputOptions: function () {
+            var i;
+            if (this.options.resources) {
+                var resources = this.options.resources;
+                if (!Array.isArray(resources)) {
+                    console.log('[ReverseGeocoding] \'options.resources\' parameter should be an array');
+                    resources = null;
+                }
+                var resourcesList = [
+                    'StreetAddress',
+                    'PositionOfInterest',
+                    'CadastralParcel',
+                    'Administratif'
+                ];
+                for (i = 0; i < resources.length; i++) {
+                    if (resourcesList.indexOf(resources[i]) === -1) {
+                        console.log('[ReverseGeocoding] options.resources : ' + resources[i] + ' is not a resource for reverse geocode');
+                    }
+                }
+            }
+            if (this.options.delimitations) {
+                var delimitations = this.options.delimitations;
+                if (!Array.isArray(delimitations)) {
+                    console.log('[ReverseGeocoding] \'options.delimitations\' parameter should be an array');
+                    delimitations = null;
+                }
+                var delimitationsList = [
+                    'Circle',
+                    'Point',
+                    'Extent'
+                ];
+                for (i = 0; i < delimitations.length; i++) {
+                    if (delimitationsList.indexOf(delimitations[i]) === -1) {
+                        console.log('[ReverseGeocoding] options.delimitations : ' + delimitations[i] + ' is not a delimitation for reverse geocode');
+                    }
+                }
+            }
+        },
+        _initGeocodingType: function () {
+            this._currentGeocodingType = 'StreetAddress';
+            var resources = this.options.resources;
+            if (!resources || resources.length === 0) {
+                this.options.resources = [
+                    'StreetAddress',
+                    'PositionOfInterest',
+                    'CadastralParcel'
+                ];
+            }
+            if (Array.isArray(resources) && resources.length) {
+                var noRightsIndexes = [];
+                for (var i = 0; i < resources.length; i++) {
+                    if (this._servicesRightManagement['Geocode'].indexOf(resources[i]) < 0) {
+                        noRightsIndexes.push(i);
+                        console.log('[ReverseGeocode] no rights for options.resources : ' + resources[i]);
+                    }
+                }
+                if (noRightsIndexes.length !== 0) {
+                    for (var j = 0; j < noRightsIndexes.length; j++) {
+                        resources.splice(noRightsIndexes[j], 1);
+                    }
+                }
+                if (resources[0] === 'StreetAddress' || resources[0] === 'PositionOfInterest' || resources[0] === 'CadastralParcel' || resources[0] === 'Administratif') {
+                    this._currentGeocodingType = resources[0];
+                }
+            }
+            var serviceOptions = this.options.reverseGeocodeOptions;
+            if (serviceOptions.filterOptions && Array.isArray(serviceOptions.filterOptions.type) && serviceOptions.filterOptions.type.length !== 0) {
+                this._currentGeocodingType = serviceOptions.filterOptions.type[0];
+            }
+        },
+        _initGeocodingDelimitation: function () {
+            this._currentGeocodingDelimitation = 'Point';
+            var delimitations = this.options.delimitations;
+            if (!delimitations || delimitations.length === 0) {
+                this.options.delimitations = [
+                    'Point',
+                    'Circle',
+                    'Extent'
+                ];
+            }
+            if (Array.isArray(delimitations) && delimitations.length) {
+                var d = delimitations[0].toLowerCase();
+                if (d === 'point' || d === 'circle' || d === 'extent') {
+                    this._currentGeocodingDelimitation = delimitations[0];
+                }
+            }
+        },
+        _initLayout: function () {
+            var container = this._createMainContainerElement();
+            var inputShow = this._showReverseGeocodingContainer = this._createShowReverseGeocodingElement();
+            container.appendChild(inputShow);
+            if (!this.options.collapsed) {
+                inputShow.checked = true;
+            }
+            var picto = this._createShowReverseGeocodingPictoElement();
+            container.appendChild(picto);
+            var reverseGeocodingPanel = this._createReverseGeocodingPanelElement();
+            var panelHeader = this._panelHeaderContainer = this._createReverseGeocodingPanelHeaderElement();
+            var returnPicto = this._returnPictoContainer = this._createReverseGeocodingPanelReturnPictoElement();
+            panelHeader.appendChild(returnPicto);
+            var panelTitle = this._panelTitleContainer = this._createReverseGeocodingPanelTitleElement();
+            panelHeader.appendChild(panelTitle);
+            var closeDiv = this._createReverseGeocodingPanelCloseElement();
+            panelHeader.appendChild(closeDiv);
+            reverseGeocodingPanel.appendChild(panelHeader);
+            var reverseGeocodingForm = this._formContainer = this._createReverseGeocodingPanelFormElement();
+            reverseGeocodingForm.appendChild(this._createReverseGeocodingFormModeChoiceGeocodingTypeElement(this.options.resources));
+            reverseGeocodingForm.appendChild(this._createReverseGeocodingFormModeChoiceGeocodingDelimitationElement(this.options.delimitations));
+            var submit = this._createReverseGeocodingSubmitFormElement();
+            reverseGeocodingForm.appendChild(submit);
+            reverseGeocodingPanel.appendChild(reverseGeocodingForm);
+            var waiting = this._waitingContainer = this._createReverseGeocodingWaitingElement();
+            reverseGeocodingPanel.appendChild(waiting);
+            var resultsPanel = this._resultsContainer = this._createReverseGeocodingResultsPanelElement();
+            var reverseGeocodingResultsList = this._resultsListContainer = this._createReverseGeocodingResultsListElement();
+            resultsPanel.appendChild(reverseGeocodingResultsList);
+            reverseGeocodingPanel.appendChild(resultsPanel);
+            container.appendChild(reverseGeocodingPanel);
+            return container;
+        },
+        _activateMapInteraction: function (map) {
+            if (this._inputFeaturesLayer === null) {
+                this._inputFeaturesLayer = new L.FeatureGroup();
+                map.addLayer(this._inputFeaturesLayer);
+                var self = this;
+                map.on('draw:created', function (e) {
+                    var layer = e.layer;
+                    var type = e.layerType;
+                    self._setFeaturePosition(layer, type);
+                    self._currentIdLayer = L.Util.stamp(layer);
+                    self._setFeatureLayer(layer);
+                });
+                map.on('draw:drawstart', function () {
+                    self._removeFeatureLayer(self._lastIdLayer);
+                    self._lastIdLayer = self._currentIdLayer;
+                });
+                map.on('draw:drawstop', function () {
+                });
+            }
+            var delimitation = this._currentGeocodingDelimitation.toLowerCase();
+            switch (delimitation) {
+            case 'point':
+                this._activatePointInteraction(map);
+                break;
+            case 'circle':
+                this._activateCircleInteraction(map);
+                break;
+            case 'extent':
+                this._activateBoxInteraction(map);
+                break;
+            default:
+                break;
+            }
+        },
+        _removeMapInteraction: function (map) {
+            if (!map) {
+                return;
+            }
+            if (this._inputFeaturesLayer !== null) {
+                map.off('draw:created');
+                map.off('draw:drawstart');
+                map.off('draw:drawstop');
+                map.removeLayer(this._inputFeaturesLayer);
+                this._inputFeaturesLayer = null;
+            }
+            this._lastIdLayer = this._currentIdLayer = 0;
+            if (this._currentFeature) {
+                this._currentFeature.disable();
+            }
+        },
+        _activatePointInteraction: function (map) {
+            if (this._currentFeature) {
+                this._currentFeature.disable();
+            }
+            L.drawLocal.draw.handlers.marker.tooltip.start = 'click map to place search point';
+            var markerOptions = { repeatMode: true };
+            this._currentFeature = new L.Draw.Marker(map, markerOptions);
+            this._currentFeature.enable();
+        },
+        _activateCircleInteraction: function (map) {
+            if (this._currentFeature) {
+                this._currentFeature.disable();
+            }
+            var circleOptions = { repeatMode: true };
+            this._currentFeature = new L.Draw.Circle(map, circleOptions);
+            this._currentFeature.enable();
+        },
+        _activateBoxInteraction: function (map) {
+            if (this._currentFeature) {
+                this._currentFeature.disable();
+            }
+            var rectangleOptions = { repeatMode: true };
+            this._currentFeature = new L.Draw.Rectangle(map, rectangleOptions);
+            this._currentFeature.enable();
+        },
+        _setFeaturePosition: function (layer, type) {
+            var oLatLng = null;
+            if (type === 'marker') {
+                oLatLng = layer.getLatLng();
+                this._requestPosition = {
+                    x: oLatLng.lat,
+                    y: oLatLng.lng
+                };
+            } else if (type === 'circle') {
+                oLatLng = layer.getLatLng();
+                this._requestPosition = {
+                    x: oLatLng.lat,
+                    y: oLatLng.lng
+                };
+                this._requestCircleFilter = {
+                    x: oLatLng.lat,
+                    y: oLatLng.lng,
+                    radius: layer.getRadius()
+                };
+            } else if (type === 'rectangle') {
+                oLatLng = layer.getBounds();
+                var center = {
+                    lng: (oLatLng.getSouthWest().lng + oLatLng.getNorthEast().lng) / 2,
+                    lat: (oLatLng.getSouthWest().lat + oLatLng.getNorthEast().lat) / 2
+                };
+                this._requestPosition = {
+                    x: center.lat,
+                    y: center.lng
+                };
+                this._requestBboxFilter = {
+                    left: oLatLng.getSouthWest().lat,
+                    right: oLatLng.getNorthEast().lat,
+                    bottom: oLatLng.getSouthWest().lng,
+                    top: oLatLng.getNorthEast().lng
+                };
+            } else {
+            }
+        },
+        _setFeatureLayer: function (layer) {
+            if (!this._inputFeaturesLayer) {
+                return;
+            }
+            this._inputFeaturesLayer.addLayer(layer);
+        },
+        _removeFeatureLayer: function (id) {
+            if (!this._inputFeaturesLayer) {
+                return;
+            }
+            if (id === 0) {
+                return;
+            }
+            if (!id) {
+                this._inputFeaturesLayer.clearLayers();
+            } else {
+                this._inputFeaturesLayer.removeLayer(id);
+            }
+        },
+        _reverseGeocodingRequest: function (settings) {
+            var map = this._map;
+            this._removeMapInteraction(map);
+            var options = {};
+            L.Util.extend(options, this.options.reverseGeocodeOptions);
+            L.Util.extend(options, settings);
+            L.Util.extend(options, {
+                apiKey: this.options.apiKey,
+                srs: 'EPSG:4326',
+                returnFreeForm: false,
+                timeOut: 30000,
+                protocol: 'XHR'
+            });
+            var _type = options.filterOptions.type;
+            if (this._currentGeocodingDelimitation.toLowerCase() === 'circle' && this._requestCircleFilter) {
+                if (this._requestCircleFilter.radius > 1000) {
+                    this._requestCircleFilter.radius = 1000;
+                }
+                L.Util.extend(options, {
+                    filterOptions: {
+                        type: _type,
+                        circle: this._requestCircleFilter
+                    }
+                });
+            }
+            if (this._currentGeocodingDelimitation.toLowerCase() === 'extent' && this._requestBboxFilter) {
+                L.Util.extend(options, {
+                    filterOptions: {
+                        type: _type,
+                        bbox: this._requestBboxFilter
+                    }
+                });
+            }
+            this._displayWaitingContainer();
+            Gp.Services.reverseGeocode(options);
+        },
+        _displayGeocodedLocations: function (locations) {
+            this._clearLocations();
+            this._clearLocationsFeature();
+            this._reverseGeocodingLocations = locations;
+            if (!locations || locations.length === 0) {
+                this._clearInputRequest();
+                return;
+            }
+            this._formContainer.className = 'GPreverseGeocodingComponentHidden';
+            this._hideWaitingContainer();
+            this._panelTitleContainer.innerHTML = 'Résultats de la recherche';
+            this._returnPictoContainer.className = '';
+            this._resultsContainer.className = 'GPpanel';
+            this._fillGeocodedLocationListContainer(locations);
+            this._displayGeocodedLocationsOnMap(locations);
+            var map = this._map;
+            map.fitBounds(this._inputResultsLayer.getBounds());
+        },
+        _fillGeocodedLocationListContainer: function (locations) {
+            for (var i = 0; i < locations.length; i++) {
+                var location = locations[i];
+                var locationDescription = this._fillGeocodedLocationDescription(location);
+                if (locationDescription.length !== 0) {
+                    this._createReverseGeocodingResultElement(locationDescription, i);
+                }
+            }
+        },
+        _fillGeocodedLocationDescription: function (location) {
+            if (!location || !location.placeAttributes) {
+                return;
+            }
+            var attr = location.placeAttributes;
+            var locationDescription = '';
+            switch (location.type) {
+            case 'StreetAddress':
+                if (attr.street) {
+                    locationDescription += attr.number ? attr.number + ' ' : '';
+                    locationDescription += attr.street + ', ';
+                }
+                locationDescription += attr.postalCode + ' ' + attr.commune;
+                break;
+            case 'PositionOfInterest':
+                if (location.matchType === 'City' && attr.commune) {
+                    locationDescription += attr.commune;
+                    locationDescription += attr.postalCode ? ', ' + attr.postalCode : '';
+                } else if (location.matchType === 'Département' && attr.municipality) {
+                    locationDescription += attr.municipality;
+                    locationDescription += attr.postalCode ? ', ' + attr.postalCode : '';
+                } else if (location.matchType === 'Toponym' && attr.municipality) {
+                    locationDescription += attr.municipality;
+                    locationDescription += attr.postalCode ? ', ' + attr.postalCode : '';
+                    locationDescription += attr.commune ? ' ' + attr.commune : '';
+                } else {
+                    locationDescription += attr.municipality ? attr.municipality : '';
+                }
+                locationDescription += attr.nature ? ' (' + attr.nature + ') ' : '';
+                break;
+            case 'CadastralParcel':
+                locationDescription += attr.cadastralParcel ? attr.cadastralParcel : '';
+                locationDescription += attr.municipality ? ' (' + attr.municipality + ')' : '';
+                break;
+            case 'Administratif':
+                locationDescription += attr.municipality ? attr.municipality : '';
+                if (attr.inseeDepartment) {
+                    locationDescription += '(Département)';
+                } else if (attr.inseeRegion) {
+                    locationDescription += '(Région)';
+                }
+                break;
+            default:
+                locationDescription += attr.municipality ? attr.municipality : '';
+                break;
+            }
+            return locationDescription;
+        },
+        _displayGeocodedLocationsOnMap: function (locations) {
+            var map = this._map;
+            var self = this;
+            function _setHighLight(e) {
+                var layer = e.target;
+                layer.setIcon(new IconDefault('red'));
+                var div = L.DomUtil.get('ReverseGeocodedLocation_' + layer.options.id + '-' + self._uid);
+                L.DomUtil.addClass(div, 'GPreverseGeocodedLocationHighlight');
+                div.scrollIntoView(false);
+            }
+            function _resetHighLight(e) {
+                var layer = e.target;
+                layer.setIcon(new IconDefault('green'));
+                var div = L.DomUtil.get('ReverseGeocodedLocation_' + layer.options.id + '-' + self._uid);
+                L.DomUtil.removeClass(div, 'GPreverseGeocodedLocationHighlight');
+            }
+            this._inputResultsLayer = new L.FeatureGroup();
+            map.addLayer(this._inputResultsLayer);
+            for (var i = 0; i < locations.length; i++) {
+                var location = locations[i];
+                if (!location) {
+                    continue;
+                }
+                var options = {
+                    id: i,
+                    icon: new IconDefault('green'),
+                    riseOnHover: true,
+                    draggable: false,
+                    clickable: true,
+                    zIndexOffset: 1000
+                };
+                var _marker = L.marker(L.latLng(location.position.x, location.position.y), options);
+                var popupContent = '<ul>';
+                var attributes = location.placeAttributes;
+                for (var attr in attributes) {
+                    if (attributes.hasOwnProperty(attr)) {
+                        if (attr !== 'bbox') {
+                            popupContent += '<li>';
+                            popupContent += '<span class="gp-attname-others-span">' + attr.toUpperCase() + ' : </span>';
+                            popupContent += attributes[attr];
+                            popupContent += ' </li>';
+                        }
+                    }
+                }
+                popupContent += ' </ul>';
+                _marker.bindPopup(popupContent);
+                _marker.on('mouseover', _setHighLight);
+                _marker.on('mouseout', _resetHighLight);
+                this._inputResultsLayer.addLayer(_marker);
+            }
+        },
+        onShowReverseGeocodingClick: function () {
+            var map = this._map;
+            if (this._showReverseGeocodingContainer.checked) {
+                this._removeMapInteraction(map);
+            } else {
+                if (!this._waiting && !this._reverseGeocodingLocations.length) {
+                    this._activateMapInteraction(map);
+                }
+            }
+        },
+        onReverseGeocodingTypeChange: function (e) {
+            var idx = e.target.selectedIndex;
+            var value = e.target.options[idx].value;
+            if (!value) {
+                return;
+            }
+            this._currentGeocodingType = value;
+        },
+        onReverseGeocodingDelimitationChange: function (e) {
+            var idx = e.target.selectedIndex;
+            var value = e.target.options[idx].value;
+            if (!value) {
+                return;
+            }
+            this._currentGeocodingDelimitation = value;
+            this._clearInputRequest();
+            var map = this._map;
+            this._removeMapInteraction(map);
+            this._activateMapInteraction(map);
+        },
+        onGPreverseGeocodingReturnPictoClick: function () {
+            this._clearLocations();
+            this._clearLocationsFeature();
+            this._clearInputRequest();
+            this._activateMapInteraction(this._map);
+        },
+        onReverseGeocodingSubmit: function () {
+            if (!this._requestPosition) {
+                return;
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            var self = this;
+            this._reverseGeocodingRequest({
+                position: self._requestPosition,
+                filterOptions: { type: [self._currentGeocodingType] },
+                onSuccess: function (results) {
+                    if (results) {
+                        var locations = results.locations;
+                        self._displayGeocodedLocations(locations);
+                        self._hideWaitingContainer();
+                    }
+                },
+                onFailure: function (error) {
+                    self._hideWaitingContainer();
+                    self._clearLocations();
+                    self._clearLocationsFeature();
+                    self._clearInputRequest();
+                }
+            });
+        },
+        onReverseGeocodingResultClick: function (e) {
+        },
+        onReverseGeocodingResultMouseOver: function (e) {
+            var idx = ID.index(e.target.id);
+            if (e.target.classList) {
+                e.target.classList.add('GPreverseGeocodedLocationHighlight');
+            }
+            if (!this._inputResultsLayer) {
+                return;
+            }
+            this._inputResultsLayer.eachLayer(function (layer) {
+                if (layer.options.id === parseInt(idx, 10)) {
+                    layer.fire('mouseover');
+                }
+            });
+        },
+        onReverseGeocodingResultMouseOut: function (e) {
+            var idx = ID.index(e.target.id);
+            if (e.target.classList) {
+                e.target.classList.remove('GPreverseGeocodedLocationHighlight');
+            }
+            if (!this._inputResultsLayer) {
+                return;
+            }
+            this._inputResultsLayer.eachLayer(function (layer) {
+                if (layer.options.id === parseInt(idx, 10)) {
+                    layer.fire('mouseout');
+                }
+            });
+        },
+        _clearLocations: function () {
+            this._reverseGeocodingLocations = [];
+            if (this._resultsListContainer) {
+                while (this._resultsListContainer.firstChild) {
+                    this._resultsListContainer.removeChild(this._resultsListContainer.firstChild);
+                }
+            }
+        },
+        _clearLocationsFeature: function () {
+            var map = this._map;
+            if (this._inputResultsLayer !== null) {
+                map.removeLayer(this._inputResultsLayer);
+                this._inputResultsLayer = null;
+            }
+        },
+        _clearInputRequest: function () {
+            this._requestPosition = null;
+            this._requestCircleFilter = null;
+            this._requestBboxFilter = null;
+        },
+        _displayWaitingContainer: function () {
+            this._waitingContainer.className = 'GPreverseGeocodingCalcWaitingContainerVisible';
+            this._waiting = true;
+            if (this._timer) {
+                clearTimeout(this._timer);
+                this._timer = null;
+            }
+            var context = this;
+            this._timer = setTimeout(function () {
+                if (context._waiting === true) {
+                    context._hideWaitingContainer();
+                } else {
+                    if (context._timer) {
+                        clearTimeout(context._timer);
+                    }
+                }
+            }, 16000);
+        },
+        _hideWaitingContainer: function () {
+            if (this._waiting) {
+                this._waitingContainer.className = 'GPreverseGeocodingCalcWaitingContainerHidden';
+                this._waiting = false;
+                clearTimeout(this._timer);
+                this._timer = null;
+            }
+        }
+    });
+    return ReverseGeocoding;
+}(leaflet, leafletDraw, {}, gp, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, LeafletControlsUtilsIconDefault, CommonControlsReverseGeocodingDOM);
+CommonControlsRouteDOM = function (ID) {
+    var RouteDOM = {
+        _addUID: function (id) {
+            return id + '-' + this._uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GProute');
+            container.className = 'GPwidget';
+            return container;
+        },
+        _createShowRouteElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowRoute');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowRoutePictoElement: function () {
+            var context = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowRoutePicto');
+            label.className = 'GPshowAdvancedToolPicto';
+            label.htmlFor = this._addUID('GPshowRoute');
+            label.title = 'Ouvrir le calcul d\'itinéraire';
+            if (label.addEventListener) {
+                label.addEventListener('click', function (e) {
+                    context.onShowRoutePanelClick(e);
+                });
+            } else if (label.attachEvent) {
+                label.attachEvent('onclick', function (e) {
+                    context.onShowRoutePanelClick(e);
+                });
+            }
+            var spanOpen = document.createElement('span');
+            spanOpen.id = this._addUID('GPshowRouteOpen');
+            spanOpen.className = 'GPshowAdvancedToolOpen';
+            label.appendChild(spanOpen);
+            return label;
+        },
+        _createRoutePanelElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GProutePanel');
+            div.className = 'GPpanel';
+            return div;
+        },
+        _createRoutePanelHeaderElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.className = 'GPpanelHeader';
+            var div = document.createElement('div');
+            div.className = 'GPpanelTitle';
+            div.innerHTML = 'Calcul d\'itinéraire';
+            container.appendChild(div);
+            var divClose = document.createElement('div');
+            divClose.id = this._addUID('GProutePanelClose');
+            divClose.className = 'GPpanelClose';
+            divClose.title = 'Masquer le panneau';
+            if (divClose.addEventListener) {
+                divClose.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPshowRoutePicto')).click();
+                }, false);
+            } else if (divClose.attachEvent) {
+                divClose.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPshowRoutePicto')).click();
+                });
+            }
+            container.appendChild(divClose);
+            return container;
+        },
+        _createRoutePanelFormElement: function () {
+            var self = this;
+            var form = document.createElement('form');
+            form.id = this._addUID('GProuteForm');
+            form.setAttribute('onkeypress', 'return event.keyCode != 13;');
+            form.addEventListener('submit', function (e) {
+                console.log(e);
+                e.preventDefault();
+                var points = document.getElementsByClassName(self._addUID('GPlocationPoint'));
+                var start = points[0].childNodes[0].id;
+                var end = points[points.length - 1].childNodes[0].id;
+                var startID = ID.index(start);
+                var endID = ID.index(end);
+                if (document.getElementById(self._addUID('GPlocationOrigin_' + startID)).value == '' && document.getElementById(self._addUID('GPlocationOriginCoords_' + startID)).value == '' || document.getElementById(self._addUID('GPlocationOrigin_' + endID)).value == '' && document.getElementById(self._addUID('GPlocationOriginCoords_' + endID)).value == '') {
+                    return false;
+                }
+                var id;
+                document.getElementById(self._addUID('GProuteResultsStages')).innerHTML = '';
+                for (var i = 0; i < points.length; i++) {
+                    var tag = points[i].childNodes[0].id;
+                    id = ID.index(tag);
+                    if (document.getElementById(self._addUID('GPlocationPoint_' + id)).className == 'GPflexInput GPlocationStageFlexInput') {
+                        var resultStage = document.createElement('div');
+                        resultStage.className = 'GProuteResultsStages';
+                        var resultStageLabel = document.createElement('div');
+                        resultStageLabel.className = 'GProuteResultStageLabel';
+                        resultStageLabel.innerHTML = document.getElementById(self._addUID('GPlocationOriginLabel_' + id)).innerHTML + ' :';
+                        resultStage.appendChild(resultStageLabel);
+                        var resultStageValue = document.createElement('div');
+                        resultStageValue.className = 'GProuteResultStageValue';
+                        var elementCoords = document.getElementById(self._addUID('GPlocationOriginCoords_' + id));
+                        var stageCoords = elementCoords.value;
+                        var visible = elementCoords.className === 'GPlocationOriginVisible' ? true : false;
+                        if (stageCoords != null && stageCoords != '' && visible) {
+                            resultStageValue.innerHTML = stageCoords;
+                        } else {
+                            resultStageValue.innerHTML = document.getElementById(self._addUID('GPlocationOrigin_' + id)).value;
+                        }
+                        resultStage.appendChild(resultStageValue);
+                        if (resultStageValue.innerHTML != '') {
+                            document.getElementById(self._addUID('GProuteResultsStages')).appendChild(resultStage);
+                        }
+                    }
+                }
+                var modeComputation = null;
+                if (document.getElementById(self._addUID('GProuteComputationSelect'))) {
+                    var select = document.getElementById(self._addUID('GProuteResultsComputationSelect'));
+                    select.selectedIndex = document.getElementById(self._addUID('GProuteComputationSelect')).selectedIndex;
+                    modeComputation = select.options[select.selectedIndex].value;
+                }
+                var modeTransport = null;
+                if (document.getElementById(self._addUID('GProuteTransportCar'))) {
+                    if (document.getElementById(self._addUID('GProuteTransportCar')).checked) {
+                        modeTransport = document.getElementById(self._addUID('GProuteTransportCar')).value;
+                    }
+                }
+                if (document.getElementById(self._addUID('GProuteTransportPedestrian'))) {
+                    if (document.getElementById(self._addUID('GProuteTransportPedestrian')).checked) {
+                        modeTransport = document.getElementById(self._addUID('GProuteTransportPedestrian')).value;
+                    }
+                }
+                var exclusions = [];
+                var exclusionsElement = document.getElementsByClassName('GProuteExclusionsOption');
+                for (var j = 0; j < exclusionsElement.length; j++) {
+                    id = exclusionsElement[j].htmlFor;
+                    var el = document.getElementById(id);
+                    if (!el.checked) {
+                        exclusions.push(el.value);
+                    }
+                }
+                self.onRouteComputationSubmit({
+                    computation: modeComputation,
+                    transport: modeTransport,
+                    exclusions: exclusions
+                });
+                return false;
+            });
+            return form;
+        },
+        _createRoutePanelResultsElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GProuteResultsPanel');
+            container.className = 'GProuteComponentHidden';
+            container.appendChild(this._createRouteResultsStagesElement());
+            container.appendChild(this._createRouteResultsElement());
+            var divBorderUp = document.createElement('div');
+            divBorderUp.className = 'GPfakeBorder GPfakeBorderLeft';
+            container.appendChild(divBorderUp);
+            container.appendChild(this._createRouteShowResultsDetailsElement());
+            var labelShow = document.createElement('label');
+            labelShow.htmlFor = this._addUID('GProuteResultsShowDetails');
+            labelShow.innerHTML = 'Afficher le détail';
+            container.appendChild(labelShow);
+            var labelHide = document.createElement('label');
+            labelHide.htmlFor = this._addUID('GProuteResultsShowDetails');
+            labelHide.innerHTML = 'Masquer le détail';
+            container.appendChild(labelHide);
+            var divBorderDown = document.createElement('div');
+            divBorderDown.className = 'GPfakeBorder';
+            container.appendChild(divBorderDown);
+            container.appendChild(this._createRouteResultsDetailsElement());
+            return container;
+        },
+        _createRouteWaitingElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GProuteCalcWaitingContainer');
+            div.className = 'GProuteCalcWaitingContainerHidden';
+            var p = document.createElement('p');
+            p.className = 'GProuteCalcWaiting';
+            p.innerHTML = 'Calcul en cours...';
+            div.appendChild(p);
+            return div;
+        },
+        _createRouteResultsStagesElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GProuteResultsStages');
+            return div;
+        },
+        _createRouteResultsElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.id = this._addUID('GProuteResults');
+            var divValue = document.createElement('div');
+            divValue.id = this._addUID('GProuteResultsValues');
+            container.appendChild(divValue);
+            var divMode = document.createElement('div');
+            divMode.id = this._addUID('GProuteResultsMode');
+            var select = document.createElement('select');
+            select.id = this._addUID('GProuteResultsComputationSelect');
+            select.className = 'GPinputSelect';
+            select.addEventListener('change', function (e) {
+                self.onRouteModeComputationChangeAndRun(e);
+            });
+            var computes = [
+                {
+                    code: 'fastest',
+                    label: 'Plus rapide'
+                },
+                {
+                    code: 'shortest',
+                    label: 'Plus court'
+                }
+            ];
+            for (var i = 0; i < computes.length; i++) {
+                var option = document.createElement('option');
+                option.value = computes[i].code;
+                option.text = computes[i].label;
+                select.appendChild(option);
+            }
+            divMode.appendChild(select);
+            container.appendChild(divMode);
+            var divNew = document.createElement('div');
+            divNew.id = this._addUID('GProuteResultsNew');
+            divNew.title = 'Modifier le calcul';
+            divNew.addEventListener('click', function (e) {
+                document.getElementById(self._addUID('GProuteResultsPanel')).className = 'GProuteComponentHidden';
+                document.getElementById(self._addUID('GProuteForm')).className = '';
+                self.onShowRouteResultsNewClick(e);
+            });
+            container.appendChild(divNew);
+            return container;
+        },
+        _addRouteResultsValuesElement: function (distance, duration, fconvert) {
+            var div = document.getElementById(this._addUID('GProuteResultsValues'));
+            if (div.childElementCount) {
+                while (div.firstChild) {
+                    div.removeChild(div.firstChild);
+                }
+            }
+            var containerDistance = document.createElement('div');
+            containerDistance.className = 'GProuteResultsValue';
+            var labelDistance = document.createElement('label');
+            labelDistance.className = 'GProuteResultsValueLabel';
+            labelDistance.innerHTML = 'Distance :';
+            containerDistance.appendChild(labelDistance);
+            var distanceLabel = 0;
+            var isKm = parseInt(distance / 1000, 10);
+            if (!isKm) {
+                distanceLabel = Math.round(distance) + ' m';
+            } else {
+                var distanceArrondi = Math.round(distance);
+                distanceArrondi = distanceArrondi / 1000;
+                distanceLabel = distanceArrondi + ' km';
+            }
+            var divDistance = document.createElement('div');
+            divDistance.id = this._addUID('GProuteResultsValueDist');
+            divDistance.innerHTML = distanceLabel;
+            containerDistance.appendChild(divDistance);
+            div.appendChild(containerDistance);
+            var containerDuration = document.createElement('div');
+            containerDuration.className = 'GProuteResultsValue';
+            var labelDuration = document.createElement('label');
+            labelDuration.className = 'GProuteResultsValueLabel';
+            labelDuration.innerHTML = 'Durée :';
+            containerDuration.appendChild(labelDuration);
+            var divDuration = document.createElement('div');
+            divDuration.id = this._addUID('GProuteResultsValueDist');
+            divDuration.innerHTML = fconvert(duration);
+            containerDuration.appendChild(divDuration);
+            div.appendChild(containerDuration);
+            return div;
+        },
+        _createRouteShowResultsDetailsElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GProuteResultsShowDetails');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createRouteResultsDetailsElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GProuteResultsDetails');
+            return div;
+        },
+        _addRouteResultsDetailsElement: function (instructions, fconvert) {
+            var context = this;
+            var div = document.getElementById(this._addUID('GProuteResultsDetails'));
+            if (div.childElementCount) {
+                while (div.firstChild) {
+                    div.removeChild(div.firstChild);
+                }
+            }
+            var distanceCumul = 0;
+            var durationCumul = 0;
+            for (var i = 0; i < instructions.length; i++) {
+                var id = i + 1;
+                var o = instructions[i];
+                var divNum = document.createElement('div');
+                divNum.className = 'GProuteResultsDetailsNumber';
+                divNum.innerHTML = id + '.';
+                div.appendChild(divNum);
+                durationCumul += parseFloat(o.duration);
+                distanceCumul += parseFloat(o.distance);
+                var distance = 0;
+                var isCumulKm = parseInt(distanceCumul / 1000, 10);
+                if (!isCumulKm) {
+                    distance = Math.round(distanceCumul) + ' m';
+                } else {
+                    var distanceArrondi = Math.round(distanceCumul);
+                    distanceArrondi = distanceArrondi / 1000;
+                    distance = distanceArrondi + ' km';
+                }
+                var divIns = document.createElement('div');
+                divIns.className = 'GProuteResultsDetailsInstruction';
+                divIns.id = this._addUID('GProuteResultsDetailsInstruction_' + id);
+                divIns.title = 'distance : ' + distance + ' / ' + 'temps : ' + fconvert(durationCumul);
+                divIns.innerHTML = o.instruction;
+                divIns.addEventListener('mouseover', function (e) {
+                    context.onRouteResultsDetailsMouseOver(e);
+                });
+                divIns.addEventListener('mouseout', function (e) {
+                    context.onRouteResultsDetailsMouseOut(e);
+                });
+                divIns.addEventListener('click', function (e) {
+                    if (typeof context.onRouteResultsDetailsClick === 'function') {
+                        context.onRouteResultsDetailsClick(e);
+                    }
+                });
+                div.appendChild(divIns);
+            }
+            return div;
+        },
+        _createRoutePanelFormPointElement: function (n, text, visibility) {
+            var context = this;
+            var div = document.createElement('div');
+            div.id = 'GProutePoint' + n;
+            div.className = visibility ? 'GPflexInput GProuteStageFlexInput' : 'GPflexInput GProuteStageFlexInputHidden';
+            var labelOrigin = document.createElement('label');
+            labelOrigin.id = 'GProuteOriginLabel' + n;
+            labelOrigin.htmlFor = 'GProuteOrigin' + n;
+            labelOrigin.innerHTML = text;
+            labelOrigin.addEventListener('click', function () {
+                var i = this.id.charAt(this.id.length - 1);
+                document.getElementById('GProuteOriginCoords' + i).value = '';
+                for (var j = 1; j < 8; j++) {
+                    document.getElementById('GProutePoint' + j).style.display = 'flex';
+                }
+                document.getElementById('GProuteForm').className = '';
+                document.getElementById('GProuteOriginPointer' + i).checked = false;
+                document.getElementById('GProuteOrigin' + i).className = 'GProuteOriginVisible';
+                document.getElementById('GProuteOriginCoords' + i).className = 'GProuteOriginHidden';
+            });
+            div.appendChild(labelOrigin);
+            var inputOrigin = document.createElement('input');
+            inputOrigin.id = 'GProuteOrigin' + n;
+            inputOrigin.className = 'GProuteOriginVisible';
+            inputOrigin.type = 'text';
+            inputOrigin.placeholder = 'Saisir une adresse';
+            inputOrigin.addEventListener('keyup', function (e) {
+                var charCode = e.which || e.keyCode;
+                if (charCode === 13 || charCode === 10) {
+                    return;
+                }
+                var i = this.id.charAt(this.id.length - 1);
+                if (document.getElementById('GProuteOrigin' + i).value.length > 2) {
+                    document.getElementById('GProuteAutoCompleteList' + i).style.display = 'block';
+                } else {
+                    document.getElementById('GProuteAutoCompleteList' + i).style.display = 'none';
+                }
+                context.onAutoCompleteSearchText(e);
+            });
+            inputOrigin.addEventListener('blur', function () {
+                var i = this.id.charAt(this.id.length - 1);
+                document.getElementById('GProuteAutoCompleteList' + i).style.display = 'none';
+            });
+            div.appendChild(inputOrigin);
+            var inputOriginCoord = document.createElement('input');
+            inputOriginCoord.id = 'GProuteOriginCoords' + n;
+            inputOriginCoord.className = 'GProuteOriginHidden';
+            inputOriginCoord.type = 'text';
+            inputOriginCoord.disabled = true;
+            div.appendChild(inputOriginCoord);
+            var inputOriginPointer = document.createElement('input');
+            inputOriginPointer.id = 'GProuteOriginPointer' + n;
+            inputOriginPointer.type = 'checkbox';
+            div.appendChild(inputOriginPointer);
+            var labelOriginPointer = document.createElement('label');
+            labelOriginPointer.id = 'GProuteOriginPointerImg' + n;
+            labelOriginPointer.htmlFor = 'GProuteOriginPointer' + n;
+            labelOriginPointer.className = 'GProuteOriginPointerImg';
+            labelOriginPointer.title = 'Pointer un lieu sur la carte';
+            labelOriginPointer.addEventListener('click', function (evt) {
+                evt.preventDefault();
+                evt.stopPropagation();
+                var i = this.id.charAt(this.id.length - 1);
+                var j;
+                for (j = 1; j < 8; j++) {
+                    if (i != j) {
+                        document.getElementById('GProuteOriginPointer' + j).checked = false;
+                        if (document.getElementById('GProuteOriginCoords' + j).value == 'Pointer un lieu sur la carte') {
+                            document.getElementById('GProuteOriginCoords' + j).value = '';
+                            document.getElementById('GProuteOrigin' + j).className = 'GProuteOriginVisible';
+                            document.getElementById('GProuteOriginCoords' + j).className = 'GProuteOriginHidden';
+                        }
+                    }
+                }
+                if (document.getElementById('GProuteOriginPointer' + i).checked) {
+                    document.getElementById('GProuteOriginCoords' + i).value = '';
+                    for (j = 1; j < 8; j++) {
+                        document.getElementById('GProutePoint' + j).style.display = 'flex';
+                    }
+                    document.getElementById('GProuteForm').className = '';
+                    document.getElementById('GProuteOriginPointer' + i).checked = false;
+                    document.getElementById('GProuteOrigin' + i).className = 'GProuteOriginVisible';
+                    document.getElementById('GProuteOriginCoords' + i).className = 'GProuteOriginHidden';
+                } else {
+                    document.getElementById('GProuteOriginCoords' + i).value = 'Pointer un lieu sur la carte';
+                    for (j = 1; j < 8; j++) {
+                        if (i == j) {
+                            document.getElementById('GProutePoint' + j).style.display = 'flex';
+                        } else {
+                            document.getElementById('GProutePoint' + j).style.display = 'none';
+                        }
+                    }
+                    document.getElementById('GProuteForm').className = 'GProuteFormMini';
+                    document.getElementById('GProuteOriginPointer' + i).checked = true;
+                    document.getElementById('GProuteOrigin' + i).className = 'GProuteOriginHidden';
+                    document.getElementById('GProuteOriginCoords' + i).className = 'GProuteOriginVisible';
+                }
+                context.onRouteMapPointClick(evt);
+            });
+            div.appendChild(labelOriginPointer);
+            return div;
+        },
+        _createRoutePanelFormRemoveStageElement: function (n) {
+            var context = this;
+            var divRm = document.createElement('div');
+            divRm.id = 'GProuteStageRemove' + n;
+            divRm.className = 'GProuteStageRemove';
+            divRm.title = 'Supprimer l\'étape';
+            if (n != 1 && n != 7) {
+                divRm.addEventListener('click', function (e) {
+                    var i = this.id.charAt(this.id.length - 1);
+                    document.getElementById('GProutePoint' + i).className = 'GPflexInput GProuteStageFlexInputHidden';
+                    document.getElementById('GProuteOrigin' + i).value = '';
+                    document.getElementById('GProuteOrigin' + i).className = 'GProuteOriginVisible';
+                    document.getElementById('GProuteOriginCoords' + i).value = '';
+                    document.getElementById('GProuteOriginCoords' + i).className = 'GProuteOriginHidden';
+                    document.getElementById('GProuteStageAdd').style.display = '';
+                    var exclusionsPictoTop = document.getElementById('GPshowRouteExclusionsPicto').style.top;
+                    document.getElementById('GPshowRouteExclusionsPicto').style.top = (parseInt(exclusionsPictoTop, 10) - 33).toString() + 'px';
+                    context.onRouteRemovePointClick(e);
+                });
+            }
+            return divRm;
+        },
+        _createRoutePanelFormAddStageElement: function () {
+            var context = this;
+            var divAdd = document.createElement('div');
+            divAdd.id = 'GProuteStageAdd';
+            divAdd.title = 'Ajouter une étape';
+            divAdd.addEventListener('click', function (e) {
+                var lastStage = 1;
+                var nbStages = 0;
+                for (var i = 2; i < 7; i++) {
+                    if (document.getElementById('GProutePoint' + i).className == 'GPflexInput GProuteStageFlexInputHidden') {
+                        if (lastStage == 1) {
+                            lastStage = i;
+                        }
+                    } else {
+                        nbStages++;
+                    }
+                }
+                if (lastStage < 7) {
+                    document.getElementById('GProutePoint' + lastStage).className = 'GPflexInput GProuteStageFlexInput';
+                    var exclusionsPictoTop = document.getElementById('GPshowRouteExclusionsPicto').style.top;
+                    document.getElementById('GPshowRouteExclusionsPicto').style.top = (parseInt(exclusionsPictoTop, 10) + 33).toString() + 'px';
+                }
+                if (nbStages == 4) {
+                    document.getElementById('GProuteStageAdd').style.display = 'none';
+                }
+                context.onRouteAddPointClick(e);
+            });
+            return divAdd;
+        },
+        _createRoutePanelFormAutoCompleteListElement: function (n) {
+            var context = this;
+            var div = document.createElement('div');
+            div.id = 'GProuteAutoCompleteList' + n;
+            div.className = 'GPadvancedAutoCompleteList';
+            if (div.addEventListener) {
+                div.addEventListener('click', function (e) {
+                    context.onAutoCompletedResultsItemClick(e);
+                    document.getElementById('GProuteAutoCompleteList' + n).style.display = 'none';
+                }, false);
+            } else if (div.attachEvent) {
+                div.attachEvent('onclick', function (e) {
+                    context.onAutoCompletedResultsItemClick(e);
+                    document.getElementById('GProuteAutoCompleteList' + n).style.display = 'none';
+                });
+            }
+            return div;
+        },
+        _createRouteAutoCompletedLocationElement: function (location, n, id) {
+            var container = document.getElementById('GProuteAutoCompleteList' + n);
+            var div = document.createElement('div');
+            div.id = 'AutoCompletedLocation' + id;
+            div.className = 'GPautoCompleteProposal';
+            div.innerHTML = location.fullText;
+            container.appendChild(div);
+        },
+        _createRoutePanelFormModeChoiceElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GProuteModeChoice');
+            return div;
+        },
+        _createRoutePanelFormModeChoiceTransportElement: function (transports) {
+            var context = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GProuteTransportChoice');
+            var span = document.createElement('span');
+            span.className = 'GProuteModeLabel';
+            span.innerHTML = 'Mode de transport';
+            div.appendChild(span);
+            for (var i = 0; i < transports.length; i++) {
+                var transport = transports[i];
+                if (transport === 'Voiture') {
+                    var inputCar = document.createElement('input');
+                    inputCar.id = this._addUID('GProuteTransportCar');
+                    inputCar.type = 'radio';
+                    inputCar.name = 'GProuteTransport';
+                    inputCar.value = 'Voiture';
+                    if (i === 0) {
+                        inputCar.checked = true;
+                    }
+                    if (inputCar.addEventListener) {
+                        inputCar.addEventListener('change', function (e) {
+                            context.onRouteModeTransportChange(e);
+                        });
+                    } else if (inputCar.attachEvent) {
+                        inputCar.attachEvent('onchange', function (e) {
+                            context.onRouteModeTransportChange(e);
+                        });
+                    }
+                    div.appendChild(inputCar);
+                    var labelCar = document.createElement('label');
+                    labelCar.className = 'GProuteTransportImg';
+                    labelCar.htmlFor = this._addUID('GProuteTransportCar');
+                    labelCar.title = 'Voiture';
+                    div.appendChild(labelCar);
+                }
+                if (transport === 'Pieton') {
+                    var inputPedestrian = document.createElement('input');
+                    inputPedestrian.id = this._addUID('GProuteTransportPedestrian');
+                    inputPedestrian.type = 'radio';
+                    inputPedestrian.name = 'GProuteTransport';
+                    inputPedestrian.value = 'Pieton';
+                    if (i === 0) {
+                        inputPedestrian.checked = true;
+                    }
+                    if (inputPedestrian.addEventListener) {
+                        inputPedestrian.addEventListener('change', function (e) {
+                            context.onRouteModeTransportChange(e);
+                        });
+                    } else if (inputPedestrian.attachEvent) {
+                        inputPedestrian.attachEvent('onchange', function (e) {
+                            context.onRouteModeTransportChange(e);
+                        });
+                    }
+                    div.appendChild(inputPedestrian);
+                    var labelPedestrian = document.createElement('label');
+                    labelPedestrian.className = 'GProuteTransportImg';
+                    labelPedestrian.htmlFor = this._addUID('GProuteTransportPedestrian');
+                    labelPedestrian.title = 'Piéton';
+                    div.appendChild(labelPedestrian);
+                }
+            }
+            return div;
+        },
+        _createRoutePanelFormModeChoiceComputeElement: function () {
+            var context = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GProuteComputationChoice');
+            var span = document.createElement('span');
+            span.className = 'GProuteModeLabel';
+            span.innerHTML = 'Mode de calcul';
+            div.appendChild(span);
+            var select = document.createElement('select');
+            select.id = this._addUID('GProuteComputationSelect');
+            select.className = 'GPinputSelect';
+            select.addEventListener('change', function (e) {
+                context.onRouteModeComputationChange(e);
+            });
+            var computes = [
+                {
+                    code: 'fastest',
+                    label: 'Plus rapide'
+                },
+                {
+                    code: 'shortest',
+                    label: 'Plus court'
+                }
+            ];
+            for (var i = 0; i < computes.length; i++) {
+                var option = document.createElement('option');
+                option.value = computes[i].code;
+                option.text = computes[i].label;
+                select.appendChild(option);
+            }
+            div.appendChild(select);
+            return div;
+        },
+        _createShowRouteExclusionsElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowRouteExclusions');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowRouteExclusionsPictoElement: function () {
+            var context = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowRouteExclusionsPicto');
+            label.className = 'GPshowMoreOptions GPshowRouteExclusionsPicto';
+            label.htmlFor = this._addUID('GPshowRouteExclusions');
+            label.title = 'Exclusions';
+            label.style.top = '185px';
+            if (label.addEventListener) {
+                label.addEventListener('click', function (e) {
+                    context.onShowRouteExclusionsClick(e);
+                });
+            } else if (label.attachEvent) {
+                label.attachEvent('onclick', function (e) {
+                    context.onShowRouteExclusionsClick(e);
+                });
+            }
+            return label;
+        },
+        _createRoutePanelFormExclusionsElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GProuteExclusions');
+            var span = document.createElement('span');
+            span.className = 'GProuteExclusionsLabel';
+            span.innerHTML = 'Passages autorisés';
+            div.appendChild(span);
+            return div;
+        },
+        _createRoutePanelFormExclusionOptionsElement: function (exclusions) {
+            var context = this;
+            var div = document.createElement('div');
+            div.className = 'GProuteExclusionsOptions';
+            for (var value in exclusions) {
+                if (exclusions.hasOwnProperty(value)) {
+                    var status = exclusions[value];
+                    switch (value) {
+                    case 'toll':
+                        var inputToll = document.createElement('input');
+                        inputToll.id = this._addUID('GProuteExclusionsToll');
+                        inputToll.type = 'checkbox';
+                        inputToll.value = 'Toll';
+                        inputToll.checked = !status;
+                        if (inputToll.addEventListener) {
+                            inputToll.addEventListener('change', function (e) {
+                                context.onRouteExclusionsChange(e);
+                            });
+                        } else if (inputToll.attachEvent) {
+                            inputToll.attachEvent('onchange', function (e) {
+                                context.onRouteExclusionsChange(e);
+                            });
+                        }
+                        div.appendChild(inputToll);
+                        var labelToll = document.createElement('label');
+                        labelToll.className = 'GProuteExclusionsOption';
+                        labelToll.htmlFor = this._addUID('GProuteExclusionsToll');
+                        labelToll.innerHTML = 'Péages';
+                        div.appendChild(labelToll);
+                        break;
+                    case 'tunnel':
+                        var inputTunnel = document.createElement('input');
+                        inputTunnel.id = this._addUID('GProuteExclusionsTunnel');
+                        inputTunnel.type = 'checkbox';
+                        inputTunnel.value = 'Tunnel';
+                        inputTunnel.checked = !status;
+                        if (inputTunnel.addEventListener) {
+                            inputTunnel.addEventListener('change', function (e) {
+                                context.onRouteExclusionsChange(e);
+                            });
+                        } else if (inputTunnel.attachEvent) {
+                            inputTunnel.attachEvent('onchange', function (e) {
+                                context.onRouteExclusionsChange(e);
+                            });
+                        }
+                        div.appendChild(inputTunnel);
+                        var labelTunnel = document.createElement('label');
+                        labelTunnel.className = 'GProuteExclusionsOption';
+                        labelTunnel.htmlFor = this._addUID('GProuteExclusionsTunnel');
+                        labelTunnel.innerHTML = 'Tunnels';
+                        div.appendChild(labelTunnel);
+                        break;
+                    case 'bridge':
+                        var inputBridge = document.createElement('input');
+                        inputBridge.id = this._addUID('GProuteExclusionsBridge');
+                        inputBridge.type = 'checkbox';
+                        inputBridge.value = 'Bridge';
+                        inputBridge.checked = !status;
+                        if (inputBridge.addEventListener) {
+                            inputBridge.addEventListener('change', function (e) {
+                                context.onRouteExclusionsChange(e);
+                            });
+                        } else if (inputBridge.attachEvent) {
+                            inputBridge.attachEvent('onchange', function (e) {
+                                context.onRouteExclusionsChange(e);
+                            });
+                        }
+                        div.appendChild(inputBridge);
+                        var labelBridge = document.createElement('label');
+                        labelBridge.className = 'GProuteExclusionsOption';
+                        labelBridge.htmlFor = this._addUID('GProuteExclusionsBridge');
+                        labelBridge.innerHTML = 'Ponts';
+                        div.appendChild(labelBridge);
+                        break;
+                    }
+                }
+            }
+            return div;
+        },
+        _createRouteSubmitFormElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GProuteSubmit');
+            input.className = 'GPinputSubmit';
+            input.type = 'submit';
+            input.value = 'Calculer';
+            return input;
+        },
+        _createRouteFormResetElement: function () {
+            var self = this;
+            var divReset = document.createElement('div');
+            divReset.id = this._addUID('GProuteReset');
+            divReset.title = 'Réinitialiser les paramètres';
+            divReset.addEventListener('click', function (e) {
+                self.onRouteResetClick(e);
+            });
+            return divReset;
+        }
+    };
+    return RouteDOM;
+}(CommonUtilsSelectorID);
+LeafletControlsRoute = function (L, woodman, Gp, RightManagement, ID, LocationSelector, RouteDOM) {
+    var Route = L.Control.extend({
+        includes: RouteDOM,
+        options: {
+            position: 'topleft',
+            collapsed: true,
+            graphs: [
+                'Voiture',
+                'Pieton'
+            ],
+            exclusions: {
+                toll: false,
+                tunnel: false,
+                bridge: false
+            },
+            disableReverse: false,
+            routeOptions: {},
+            autocompleteOptions: {}
+        },
+        initialize: function (options) {
+            L.Util.setOptions(this, options);
+            this._uid = ID.generate();
+            this._initTransport();
+            this._initExclusions();
+            this._initComputation();
+            this._waitingContainer = null;
+            this._formRouteContainer = null;
+            this._resultsRouteContainer = null;
+            this._isDesktop = this._detectSupport();
+            this._currentPoints = [];
+            this._currentTransport = null;
+            this._currentComputation = null;
+            this._currentExclusions = [];
+            this._geojsonRoute = null;
+            this._geojsonSections = null;
+            this._waiting = false;
+            this._timer = null;
+            this._currentRouteInformations = null;
+            this._resources = {};
+            this._noRightManagement = false;
+            this._checkRightsManagement();
+        },
+        onAdd: function (map) {
+            var container = this._container = this._initLayout(map);
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            return container;
+        },
+        onRemove: function () {
+        },
+        _initTransport: function () {
+            this._currentTransport = 'Voiture';
+            var transport = this.options.graphs;
+            if (!transport || transport.length === 0) {
+                this.options.graphs = [
+                    'Voiture',
+                    'Pieton'
+                ];
+            }
+            if (L.Util.isArray(transport) && transport.length) {
+                if (transport[0] === 'Voiture' || transport[0] === 'Pieton') {
+                    this._currentTransport = transport[0];
+                }
+            }
+            var serviceOptions = this.options.routeOptions;
+            if (serviceOptions.graph) {
+                this._currentTransport = serviceOptions.graph;
+            }
+        },
+        _initComputation: function () {
+            this._currentComputation = 'fastest';
+            var serviceOptions = this.options.routeOptions;
+            if (serviceOptions.routePreference) {
+                this._currentComputation = serviceOptions.routePreference;
+            }
+        },
+        _initExclusions: function () {
+            this._currentExclusions = [];
+            var exclusion = this.options.exclusions;
+            if (!exclusion || Object.keys(exclusion).length === 0) {
+                this.options.exclusions = {
+                    toll: false,
+                    tunnel: false,
+                    bridge: false
+                };
+            }
+            if (exclusion && Object.keys(exclusion).length) {
+                for (var k in exclusion) {
+                    if (exclusion.hasOwnProperty(k)) {
+                        if (exclusion.k) {
+                            this._currentExclusions.push(k);
+                        }
+                    }
+                }
+            }
+            var serviceOptions = this.options.routeOptions;
+            if (L.Util.isArray(serviceOptions.exclusions)) {
+                this._currentExclusions = serviceOptions.exclusions;
+            }
+        },
+        _checkRightsManagement: function () {
+            var _opts = null;
+            var _res = [];
+            var _key = null;
+            _key = this.options.routeOptions.apiKey;
+            _opts = this.options.routeOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = [
+                    'Voiture',
+                    'Pieton'
+                ];
+            }
+            var rightManagementRoute = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['Itineraire']
+            });
+            _key = this.options.autocompleteOptions.apiKey;
+            _opts = this.options.autocompleteOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = [
+                    'StreetAddress',
+                    'PositionOfInterest'
+                ];
+            }
+            var rightManagementAutoComplete = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['AutoCompletion']
+            });
+            if (!rightManagementRoute && !rightManagementAutoComplete) {
+                this._noRightManagement = true;
+            }
+            if (rightManagementAutoComplete) {
+                this._resources['AutoCompletion'] = {};
+                this._resources['AutoCompletion']['resources'] = rightManagementAutoComplete['AutoCompletion'];
+                this._resources['AutoCompletion']['key'] = rightManagementAutoComplete['key'];
+            }
+            if (rightManagementRoute) {
+                this._resources['Itineraire'] = {};
+                this._resources['Itineraire']['resources'] = rightManagementRoute['Itineraire'];
+                this._resources['Itineraire']['key'] = rightManagementRoute['key'];
+            }
+        },
+        _detectSupport: function () {
+            var isDesktop = true;
+            var userAgent = window.navigator.userAgent.toLowerCase();
+            if (userAgent.indexOf('iphone') !== -1 || userAgent.indexOf('ipod') !== -1 || userAgent.indexOf('ipad') !== -1 || userAgent.indexOf('android') !== -1 || userAgent.indexOf('mobile') !== -1 || userAgent.indexOf('blackberry') !== -1 || userAgent.indexOf('tablet') !== -1 || userAgent.indexOf('phone') !== -1 || userAgent.indexOf('touch') !== -1) {
+                isDesktop = false;
+            }
+            if (userAgent.indexOf('msie') !== -1 || userAgent.indexOf('trident') !== -1) {
+                isDesktop = true;
+            }
+            return isDesktop;
+        },
+        _initLayout: function (map) {
+            var container = this._createMainContainerElement();
+            var inputShow = this._showRouteContainer = this._createShowRouteElement();
+            container.appendChild(inputShow);
+            if (!this.options.collapsed) {
+                inputShow.checked = true;
+            }
+            var picto = this._createShowRoutePictoElement();
+            container.appendChild(picto);
+            var routePanel = this._createRoutePanelElement();
+            var routeHeader = this._createRoutePanelHeaderElement();
+            routePanel.appendChild(routeHeader);
+            var routeForm = this._formRouteContainer = this._createRoutePanelFormElement();
+            var points = this._createRoutePanelFormPointsElement(map);
+            for (var i = 0; i < points.length; i++) {
+                routeForm.appendChild(points[i]);
+            }
+            var choice = this._createRoutePanelFormModeChoiceElement();
+            choice.appendChild(this._createRoutePanelFormModeChoiceTransportElement(this.options.graphs));
+            choice.appendChild(this._createRoutePanelFormModeChoiceComputeElement());
+            routeForm.appendChild(choice);
+            routeForm.appendChild(this._createShowRouteExclusionsElement());
+            routeForm.appendChild(this._createShowRouteExclusionsPictoElement());
+            var exclusion = this._createRoutePanelFormExclusionsElement();
+            exclusion.appendChild(this._createRoutePanelFormExclusionOptionsElement(this.options.exclusions));
+            routeForm.appendChild(exclusion);
+            var submit = this._createRouteSubmitFormElement();
+            routeForm.appendChild(submit);
+            routePanel.appendChild(routeForm);
+            var routeResults = this._resultsRouteContainer = this._createRoutePanelResultsElement();
+            routePanel.appendChild(routeResults);
+            var waiting = this._waitingContainer = this._createRouteWaitingElement();
+            routePanel.appendChild(waiting);
+            container.appendChild(routePanel);
+            return container;
+        },
+        _createRoutePanelFormPointsElement: function (map) {
+            var points = [];
+            var count = 1;
+            var start = new LocationSelector({
+                apiKey: this.options.apiKey || null,
+                tag: {
+                    id: count,
+                    unique: this._uid,
+                    label: 'Départ',
+                    color: 'blue',
+                    display: true
+                },
+                disableReverse: this.options.disableReverse,
+                autocompleteOptions: this.options.autocompleteOptions || null
+            });
+            start.setMap(map);
+            points.push(start.getContainer());
+            this._currentPoints.push(start);
+            for (count = 2; count < 7; count++) {
+                var step = new LocationSelector({
+                    apiKey: this.options.apiKey || null,
+                    tag: {
+                        id: count,
+                        unique: this._uid,
+                        label: 'Etape',
+                        color: 'green',
+                        display: false,
+                        removeOption: true
+                    },
+                    disableReverse: this.options.disableReverse,
+                    autocompleteOptions: this.options.autocompleteOptions || null
+                });
+                step.setMap(map);
+                points.push(step.getContainer());
+                this._currentPoints.push(step);
+            }
+            var end = new LocationSelector({
+                apiKey: this.options.apiKey || null,
+                tag: {
+                    id: count,
+                    unique: this._uid,
+                    label: 'Arrivée',
+                    color: 'red',
+                    display: true,
+                    addOption: true,
+                    removeOption: false
+                },
+                disableReverse: this.options.disableReverse,
+                autocompleteOptions: this.options.autocompleteOptions || null
+            });
+            end.setMap(map);
+            points.push(end.getContainer());
+            this._currentPoints.push(end);
+            return points;
+        },
+        onShowRoutePanelClick: function (e) {
+            if (!this._geojsonSections) {
+                this._clear();
+            }
+        },
+        onRouteModeComputationChange: function (e) {
+            var idx = e.target.selectedIndex;
+            var value = e.target.options[idx].value;
+            if (!value) {
+                return;
+            }
+            this._currentComputation = value;
+        },
+        onRouteModeComputationChangeAndRun: function (e) {
+            this.onRouteModeComputationChange(e);
+            this._clearRouteResultsDetails();
+            this._clearRouteResultsGeometry();
+            this._clearRouteResultsFeatureGeometry();
+            this.onRouteComputationSubmit({
+                computation: this._currentComputation,
+                transport: this._currentTransport,
+                exclusions: this._currentExclusions
+            });
+        },
+        onRouteModeTransportChange: function (e) {
+            var value = e.target.value;
+            if (!value) {
+                return;
+            }
+            this._currentTransport = value;
+        },
+        onShowRouteExclusionsClick: function (e) {
+        },
+        onRouteExclusionsChange: function (e) {
+            var value = e.target.value;
+            var checked = e.target.checked;
+            if (!value) {
+                return;
+            }
+            var bFound = false;
+            var iFound = null;
+            for (var i = 0; i < this._currentExclusions.length; i++) {
+                if (this._currentExclusions[i] === value) {
+                    iFound = i;
+                    bFound = true;
+                }
+            }
+            if (!bFound && checked) {
+                this._currentExclusions.push(value);
+            }
+            if (bFound && !checked) {
+                this._currentExclusions[iFound] = null;
+            }
+        },
+        onRouteComputationSubmit: function (options) {
+            var points = this._currentPoints;
+            var start = points[0].getCoordinate();
+            points[0].dragging(false);
+            var end = points[points.length - 1].getCoordinate();
+            points[points.length - 1].dragging(false);
+            var step = [];
+            for (var i = 1; i < points.length - 1; i++) {
+                var coordinate = points[i].getCoordinate();
+                points[i].dragging(false);
+                if (coordinate) {
+                    step.push(coordinate);
+                }
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            this._currentTransport = options.transport;
+            this._currentComputation = options.computation;
+            this._currentExclusions = options.exclusions;
+            this._displayWaitingContainer();
+            var context = this;
+            this._requestRouting({
+                startPoint: start,
+                endPoint: end,
+                viaPoints: step,
+                graph: this._currentTransport,
+                routePreference: this._currentComputation,
+                exclusions: this._currentExclusions,
+                geometryInInstructions: true,
+                distanceUnit: 'm',
+                onSuccess: function (results) {
+                    if (results) {
+                        context._fillRouteResultsDetails(results);
+                    }
+                },
+                onFailure: function (error) {
+                    context._hideWaitingContainer();
+                    context._clearRouteResultsDetails();
+                }
+            });
+        },
+        onShowRouteResultsNewClick: function (e) {
+            var points = this._currentPoints;
+            for (var i = 0; i < points.length; i++) {
+                points[i].dragging(true);
+            }
+            this._clearRouteResultsDetails();
+            this._clearRouteResultsGeometry();
+            this._clearRouteResultsFeatureGeometry();
+        },
+        onRouteResultsDetailsMouseOver: function (e) {
+            var idx = ID.index(e.target.id);
+            if (!this._isDesktop) {
+                return;
+            }
+            if (!this._geojsonSections) {
+                return;
+            }
+            this._geojsonSections.eachLayer(function (layer) {
+                if (layer.feature.id === parseInt(idx, 10)) {
+                    layer.setStyle({
+                        weight: 10,
+                        color: '#0F9DE8',
+                        opacity: 0.5
+                    });
+                }
+            });
+        },
+        onRouteResultsDetailsMouseOut: function (e) {
+            var idx = ID.index(e.target.id);
+            if (!this._isDesktop) {
+                return;
+            }
+            if (!this._geojsonSections) {
+                return;
+            }
+            this._geojsonSections.eachLayer(function (layer) {
+                if (layer.feature.id === parseInt(idx, 10)) {
+                    layer.setStyle({
+                        color: '#ED7F10',
+                        weight: 5,
+                        opacity: 0.75
+                    });
+                }
+            });
+        },
+        onRouteResultsDetailsClick: function (e) {
+            var idx = ID.index(e.target.id);
+            var self = this;
+            if (this._isDesktop) {
+                return;
+            }
+            if (!this._geojsonSections) {
+                return;
+            }
+            var newInstruction = e.target.title;
+            var oldInstruction = e.target.innerHTML;
+            this._geojsonSections.eachLayer(function (layer) {
+                if (layer.feature.id === parseInt(idx, 10)) {
+                    e.target.innerHTML = newInstruction;
+                    layer.setStyle({
+                        weight: 10,
+                        color: '#0F9DE8',
+                        opacity: 0.5
+                    });
+                }
+            });
+            clearTimeout(1000);
+            setTimeout(function () {
+                self._geojsonSections.eachLayer(function (layer) {
+                    if (layer.feature.id === parseInt(idx, 10)) {
+                        e.target.innerHTML = oldInstruction;
+                        layer.setStyle({
+                            color: '#ED7F10',
+                            weight: 5,
+                            opacity: 0.75
+                        });
+                    }
+                });
+            }, 1000);
+        },
+        _requestRouting: function (settings) {
+            if (!settings || Object.keys(settings).length === 0) {
+                return;
+            }
+            if (!settings.startPoint) {
+                return;
+            }
+            if (!settings.endPoint) {
+                return;
+            }
+            if (this._noRightManagement) {
+                console.log('no rights for all service !?');
+                return;
+            }
+            if (!this._resources['Itineraire']) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            var resources = this._resources['Itineraire'].resources;
+            if (!resources || Object.keys(resources).length === 0) {
+                return;
+            }
+            var key = this._resources['Itineraire']['key'];
+            var options = {};
+            L.Util.extend(options, this.options.routeOptions);
+            L.Util.extend(options, settings);
+            var bFound = false;
+            for (var i = 0; i < resources.length; i++) {
+                if (resources[i] === options.graph) {
+                    bFound = true;
+                }
+            }
+            if (!bFound) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            L.Util.extend(options, { apiKey: this.options.routeOptions.apiKey || this.options.apiKey || key });
+            Gp.Services.route(options);
+        },
+        _fillRouteResultsDetails: function (results) {
+            var distance = results.totalDistance;
+            var duration = results.totalTime;
+            var instructions = this._simplifiedInstructions(results.routeInstructions);
+            if (instructions) {
+                this._fillRouteResultsDetailsContainer(distance, duration, instructions);
+            }
+            var geometry = results.routeGeometry;
+            if (geometry) {
+                this._fillRouteResultsDetailsGeometry(geometry);
+            }
+            var bGeometryInstructions = instructions[0].geometry.length !== 0 ? true : false;
+            if (instructions && bGeometryInstructions) {
+                this._fillRouteResultsDetailsFeatureGeometry(instructions);
+            }
+            var bbox = results.bbox;
+            if (bbox) {
+                var map = this._map;
+                var bounds = L.latLngBounds([
+                    bbox.bottom,
+                    bbox.left
+                ], [
+                    bbox.top,
+                    bbox.right
+                ]);
+                map.fitBounds(bounds, {
+                    padding: [
+                        1,
+                        1
+                    ]
+                });
+            }
+            this._currentRouteInformations = results;
+            this._formRouteContainer.className = 'GProuteComponentHidden';
+            this._hideWaitingContainer();
+            this._resultsRouteContainer.className = '';
+        },
+        _fillRouteResultsDetailsContainer: function (distance, duration, instructions) {
+            this._resultsRouteValuesContainer = this._addRouteResultsValuesElement(distance, duration, this._convertSecondsToTime);
+            this._resultsRouteDetailsContainer = this._addRouteResultsDetailsElement(instructions, this._convertSecondsToTime);
+        },
+        _fillRouteResultsDetailsGeometry: function (geometry) {
+            this._clearRouteResultsGeometry();
+            var map = this._map;
+            var _style = {
+                color: '#ff7800',
+                weight: 5,
+                opacity: 0.65
+            };
+            this._geojsonRoute = L.geoJson(geometry, { style: _style }).addTo(map);
+        },
+        _fillRouteResultsDetailsFeatureGeometry: function (instructions) {
+            this._clearRouteResultsFeatureGeometry();
+            var map = this._map;
+            var _style = {
+                color: '#ED7F10',
+                weight: 5,
+                opacity: 0.75
+            };
+            var _geometry = {
+                type: 'FeatureCollection',
+                features: []
+            };
+            for (var i = 0; i < instructions.length; i++) {
+                var o = instructions[i];
+                var id = i + 1;
+                _geometry.features.push({
+                    id: id,
+                    type: 'Feature',
+                    geometry: o.geometry,
+                    properties: { popupContent: '(' + id + ') distance : ' + this._convertDistance(o.distance) + ' / temps : ' + this._convertSecondsToTime(o.duration) }
+                });
+            }
+            var self = this;
+            function resetHighlight(e) {
+                var layer = e.target;
+                self._geojsonSections.resetStyle(layer);
+                var div = L.DomUtil.get('GProuteResultsDetailsInstruction_' + layer.feature.id + '-' + self._uid);
+                L.DomUtil.removeClass(div, 'GProuteResultsDetailsHighlight');
+            }
+            function highlightFeature(e) {
+                var layer = e.target;
+                layer.setStyle({
+                    weight: 10,
+                    color: '#0F9DE8',
+                    opacity: 0.5
+                });
+                var div = L.DomUtil.get('GProuteResultsDetailsInstruction_' + layer.feature.id + '-' + self._uid);
+                L.DomUtil.addClass(div, 'GProuteResultsDetailsHighlight');
+            }
+            this._geojsonSections = L.geoJson(_geometry, {
+                style: _style,
+                onEachFeature: function (feature, layer) {
+                    layer.on({
+                        mouseover: highlightFeature,
+                        mouseout: resetHighlight
+                    });
+                    layer.bindPopup(feature.properties.popupContent);
+                }
+            }).addTo(map);
+        },
+        _clear: function () {
+            this._currentTransport = null;
+            this._currentExclusions = [];
+            this._currentComputation = null;
+            this._clearRouteResultsDetails();
+            this._clearRouteResultsGeometry();
+            this._clearRouteResultsFeatureGeometry();
+            for (var i = 0; i < this._currentPoints.length; i++) {
+                this._currentPoints[i].clear();
+            }
+        },
+        _clearRouteResultsDetails: function () {
+            this._currentRouteInformations = null;
+            if (this._resultsRouteDetailsContainer) {
+                var divD = this._resultsRouteDetailsContainer;
+                if (divD.childElementCount) {
+                    while (divD.firstChild) {
+                        divD.removeChild(divD.firstChild);
+                    }
+                }
+            }
+            if (this._resultsRouteValuesContainer) {
+                var divV = this._resultsRouteValuesContainer;
+                if (divV.childElementCount) {
+                    while (divV.firstChild) {
+                        divV.removeChild(divV.firstChild);
+                    }
+                }
+            }
+        },
+        _clearRouteResultsGeometry: function () {
+            var map = this._map;
+            if (this._geojsonRoute != null) {
+                map.removeLayer(this._geojsonRoute);
+                this._geojsonRoute = null;
+            }
+        },
+        _clearRouteResultsFeatureGeometry: function () {
+            var map = this._map;
+            if (this._geojsonSections != null) {
+                map.removeLayer(this._geojsonSections);
+                this._geojsonSections = null;
+            }
+        },
+        _displayWaitingContainer: function () {
+            this._waitingContainer.className = 'GProuteCalcWaitingContainerVisible';
+            this._waiting = true;
+            if (this._timer) {
+                clearTimeout(this._timer);
+                this._timer = null;
+            }
+            var context = this;
+            this._timer = setTimeout(function () {
+                if (context._waiting === true) {
+                    context._hideWaitingContainer();
+                } else {
+                    if (context._timer) {
+                        clearTimeout(context._timer);
+                    }
+                }
+            }, 16000);
+        },
+        _hideWaitingContainer: function () {
+            if (this._waiting) {
+                this._waitingContainer.className = 'GProuteCalcWaitingContainerHidden';
+                this._waiting = false;
+                clearTimeout(this._timer);
+                this._timer = null;
+            }
+        },
+        _simplifiedInstructions: function (instructions) {
+            var newInstructions = [];
+            var current = instructions[0];
+            if (instructions.length === 1) {
+                newInstructions.push(current);
+            }
+            for (var i = 1; i < instructions.length; i++) {
+                var o = instructions[i];
+                if (o.instruction === current.instruction) {
+                    current.distance = (parseFloat(o.distance) + parseFloat(current.distance)).toString();
+                    current.duration = (parseFloat(o.duration) + parseFloat(current.duration)).toString();
+                    for (var j = 1; j < o.geometry.coordinates.length; j++) {
+                        current.geometry.coordinates.push(o.geometry.coordinates[j]);
+                    }
+                    if (i === instructions.length - 1) {
+                        newInstructions.push(current);
+                        current = null;
+                    }
+                } else {
+                    newInstructions.push(current);
+                    current = o;
+                    if (i === instructions.length - 1) {
+                        newInstructions.push(o);
+                        current = null;
+                    }
+                }
+            }
+            return newInstructions;
+        },
+        _convertSecondsToTime: function (duration) {
+            var time = '';
+            duration = Math.round(duration);
+            var hours = Math.floor(duration / (60 * 60));
+            if (!hours) {
+                hours = '00';
+            }
+            var divisor4minutes = duration % (60 * 60);
+            var minutes = Math.floor(divisor4minutes / 60);
+            if (!minutes) {
+                minutes = '00';
+            }
+            var divisor4seconds = divisor4minutes % 60;
+            var seconds = Math.ceil(divisor4seconds);
+            if (!seconds) {
+                seconds = '00';
+            }
+            time = hours + 'h ' + minutes + 'm ' + seconds + 's';
+            return time;
+        },
+        _convertDistance: function (distance) {
+            var d = '';
+            var distanceKm = parseInt(distance / 1000, 10);
+            if (!distanceKm) {
+                d = parseInt(distance, 10) + ' m';
+            } else {
+                d = distanceKm + ' km';
+            }
+            return d;
+        }
+    });
+    return Route;
+}(leaflet, {}, gp, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, LeafletControlsLocationSelector, CommonControlsRouteDOM);
+CommonControlsSearchEngineDOM = function (ID) {
+    var SearchEngineDOM = {
+        _addUID: function (id) {
+            return id + '-' + this._uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPsearchEngine');
+            container.className = 'GPwidget';
+            return container;
+        },
+        _createShowSearchEngineElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowSearchEngine');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowSearchEnginePictoElement: function () {
+            var self = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowSearchEnginePicto');
+            label.className = 'GPshowAdvancedToolPicto';
+            label.htmlFor = this._addUID('GPshowSearchEngine');
+            label.title = 'Afficher/masquer la recherche par lieux';
+            label.addEventListener('click', function () {
+                document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'none';
+                document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                var showAdvancedSearch = document.getElementById(self._addUID('GPshowAdvancedSearch'));
+                if (showAdvancedSearch) {
+                    showAdvancedSearch.style.display = null;
+                    document.getElementById(self._addUID('GPadvancedSearchPanel')).style.display = 'none';
+                }
+                var id = '#GPsearchInput-' + self._uid;
+                document.querySelector(id + ' input').disabled = false;
+                self.onShowSearchEngineClick();
+            });
+            var spanOpen = document.createElement('span');
+            spanOpen.id = this._addUID('GPshowSearchEngineOpen');
+            spanOpen.className = 'GPshowAdvancedToolOpen';
+            label.appendChild(spanOpen);
+            return label;
+        },
+        _createSearchInputElement: function () {
+            var self = this;
+            var form = document.createElement('form');
+            form.id = this._addUID('GPsearchInput');
+            form.addEventListener('submit', function (e) {
+                e.preventDefault();
+                document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'block';
+                document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'none';
+                self.onGeocodingSearchSubmit(e);
+                return false;
+            });
+            var input = document.createElement('input');
+            input.id = this._addUID('GPsearchInputText');
+            input.type = 'text';
+            input.placeholder = 'Rechercher un lieu, une adresse';
+            input.autocomplete = 'off';
+            input.addEventListener('keyup', function (e) {
+                var charCode = e.which || e.keyCode;
+                if (charCode === 13 || charCode === 10 || charCode === 38 || charCode === 40) {
+                    return;
+                }
+                document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                if (input.value.length > 2) {
+                    document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'block';
+                } else {
+                    document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'none';
+                }
+                self.onAutoCompleteSearchText(e);
+            });
+            input.addEventListener('keydown', function (e) {
+                if (true) {
+                    return;
+                }
+                var charCode = e.which || e.keyCode;
+                var container = document.getElementById(self._addUID('GPautocompleteResults'));
+                if (!container) {
+                    return;
+                }
+                var curr = container.getElementsByClassName('GPautoCompleteProposal current');
+                var list = container.getElementsByClassName('GPautoCompleteProposal');
+                var length = list.length;
+                if (!length) {
+                    return;
+                }
+                var current = null;
+                if (!curr.length) {
+                    current = list[0];
+                    current.className = 'GPautoCompleteProposal current';
+                    current.style.color = '#000000';
+                    current.style['background-color'] = '#CEDBEF';
+                    return;
+                } else {
+                    current = curr[0];
+                }
+                var index = parseInt(ID.index(current.id), 10);
+                var next = index === length - 1 ? list[0] : list[index + 1];
+                var prev = index === 0 ? list[length - 1] : list[index - 1];
+                current.style['background-color'] = '';
+                current.style.color = '';
+                prev.style['background-color'] = '';
+                prev.style.color = '';
+                next.style['background-color'] = '';
+                next.style.color = '';
+                switch (charCode) {
+                case 38:
+                    current.className = 'GPautoCompleteProposal';
+                    prev.className = 'GPautoCompleteProposal current';
+                    prev.style.color = '#000000';
+                    prev.style['background-color'] = '#CEDBEF';
+                    break;
+                case 40:
+                    current.className = 'GPautoCompleteProposal';
+                    next.className = 'GPautoCompleteProposal current';
+                    next.style.color = '#000000';
+                    next.style['background-color'] = '#CEDBEF';
+                    break;
+                case 13:
+                    current.click(e);
+                    break;
+                }
+                current.focus();
+            });
+            form.appendChild(input);
+            var div = document.createElement('div');
+            div.id = this._addUID('GPsearchInputReset');
+            div.addEventListener('click', function () {
+                document.getElementById(self._addUID('GPsearchInputText')).value = '';
+                document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'none';
+                document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                self.onSearchResetClick();
+            });
+            form.appendChild(div);
+            return form;
+        },
+        _createShowAdvancedSearchElement: function () {
+            var self = this;
+            var div = document.createElement('div');
+            div.id = this._addUID('GPshowAdvancedSearch');
+            div.className = 'GPshowAdvancedToolPicto';
+            div.title = 'Ouvrir la recherche avancée';
+            div.addEventListener('click', function () {
+                var id = '#GPsearchInput-' + self._uid;
+                document.querySelector(id + ' input').disabled = true;
+                document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'none';
+                document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                document.getElementById(self._addUID('GPshowAdvancedSearch')).style.display = 'none';
+                document.getElementById(self._addUID('GPadvancedSearchPanel')).style.display = 'inline-block';
+            });
+            var span = document.createElement('span');
+            span.id = this._addUID('GPshowAdvancedSearchOpen');
+            span.className = 'GPshowAdvancedToolOpen';
+            div.appendChild(span);
+            return div;
+        },
+        _createAdvancedSearchPanelElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPadvancedSearchPanel');
+            div.className = 'GPpanel';
+            div.style.display = 'none';
+            return div;
+        },
+        _createGeocodeResultsElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPgeocodeResultsList');
+            div.className = 'GPpanel';
+            div.style.display = 'none';
+            div.appendChild(this._createGeocodeResultsHeaderElement());
+            return div;
+        },
+        _createAutoCompleteElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPautoCompleteList');
+            div.className = 'GPautoCompleteList';
+            div.style.display = 'none';
+            return div;
+        },
+        _createAutoCompleteListElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.id = this._addUID('GPautocompleteResults');
+            if (container.addEventListener) {
+                container.addEventListener('click', function (e) {
+                    self.onAutoCompletedResultsItemClick(e);
+                    document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'none';
+                }, false);
+            } else if (container.attachEvent) {
+                container.attachEvent('onclick', function (e) {
+                    self.onAutoCompletedResultsItemClick(e);
+                    document.getElementById(self._addUID('GPautoCompleteList')).style.display = 'none';
+                });
+            }
+            return container;
+        },
+        _createAutoCompletedLocationElement: function (location, id) {
+            var container = document.getElementById(this._addUID('GPautocompleteResults'));
+            var div = document.createElement('div');
+            div.id = this._addUID('AutoCompletedLocation_' + id);
+            div.className = 'GPautoCompleteProposal';
+            div.innerHTML = location.fullText;
+            if (div.addEventListener) {
+                div.addEventListener('click', function (e) {
+                    container.click(e);
+                }, false);
+            } else if (div.attachEvent) {
+                div.attachEvent('onclick', function (e) {
+                    container.click(e);
+                });
+            }
+            container.appendChild(div);
+        },
+        _createAdvancedSearchPanelHeaderElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.className = 'GPpanelHeader';
+            var divTitle = document.createElement('div');
+            divTitle.className = 'GPpanelTitle';
+            divTitle.innerHTML = 'Recherche avancée';
+            container.appendChild(divTitle);
+            var divClose = document.createElement('div');
+            divClose.id = this._addUID('GPadvancedSearchClose');
+            divClose.className = 'GPpanelClose';
+            divClose.title = 'Fermer la recherche avancée';
+            if (divClose.addEventListener) {
+                divClose.addEventListener('click', function () {
+                    var id = '#GPsearchInput-' + self._uid;
+                    document.querySelector(id + ' input').disabled = false;
+                    document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                    document.getElementById(self._addUID('GPshowAdvancedSearch')).style.display = 'inline-block';
+                    document.getElementById(self._addUID('GPadvancedSearchPanel')).style.display = 'none';
+                }, false);
+            } else if (divClose.attachEvent) {
+                divClose.attachEvent('onclick', function () {
+                    var id = '#GPsearchInput-' + self._uid;
+                    document.querySelector(id + ' input').disabled = false;
+                    document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                    document.getElementById(self._addUID('GPshowAdvancedSearch')).style.display = 'inline-block';
+                    document.getElementById(self._addUID('GPadvancedSearchPanel')).style.display = 'none';
+                });
+            }
+            container.appendChild(divClose);
+            return container;
+        },
+        _createAdvancedSearchPanelFormElement: function (advancedSearchCodes) {
+            var self = this;
+            var form = document.createElement('form');
+            form.id = this._addUID('GPadvancedSearchForm');
+            form.addEventListener('submit', function (e) {
+                e.preventDefault();
+                var data = [];
+                var id = '#GPadvancedSearchFilters-' + self._uid;
+                var matchesFilters = document.querySelectorAll(id + ' > div > div > input');
+                for (var i = 0; i < matchesFilters.length; i++) {
+                    var element = matchesFilters[i];
+                    data.push({
+                        key: element.name,
+                        value: element.value
+                    });
+                }
+                self.onGeocodingAdvancedSearchSubmit(e, data);
+                document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'block';
+                return false;
+            });
+            var div = document.createElement('div');
+            div.className = 'GPflexInput';
+            var label = document.createElement('label');
+            label.className = 'GPadvancedSearchCodeLabel';
+            label.innerHTML = 'Recherche par';
+            div.appendChild(label);
+            var select = this._createAdvancedSearchFormCodeElement(advancedSearchCodes);
+            div.appendChild(select);
+            form.appendChild(div);
+            return form;
+        },
+        _createAdvancedSearchFormCodeElement: function (codes) {
+            var self = this;
+            var select = document.createElement('select');
+            select.id = this._addUID('GPadvancedSearchCode');
+            select.className = 'GPadvancedSearchCode';
+            select.addEventListener('change', function (e) {
+                self.onGeocodingAdvancedSearchCodeChange(e);
+            }, false);
+            if (!codes) {
+                codes = [
+                    {
+                        id: 'PositionOfInterest',
+                        title: 'Lieux/toponymes'
+                    },
+                    {
+                        id: 'StreetAddress',
+                        title: 'Adresses'
+                    },
+                    {
+                        id: 'CadastralParcel',
+                        title: 'Parcelles cadastrales'
+                    },
+                    {
+                        id: 'Administratif',
+                        title: 'Administratif'
+                    }
+                ];
+            }
+            for (var i = 0; i < codes.length; i++) {
+                var option = document.createElement('option');
+                option.value = codes[i].id;
+                option.text = codes[i].title;
+                select.appendChild(option);
+            }
+            return select;
+        },
+        _createAdvancedSearchFormInputElement: function () {
+            var input = document.createElement('input');
+            input.type = 'submit';
+            input.id = this._addUID('GPadvancedSearchSubmit');
+            input.className = 'GPinputSubmit';
+            input.value = 'Chercher';
+            return input;
+        },
+        _createAdvancedSearchFormFiltersElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPadvancedSearchFilters');
+            return container;
+        },
+        _createAdvancedSearchFiltersTableElement: function (code, display) {
+            var container = document.createElement('div');
+            container.id = this._addUID(code);
+            if (!display) {
+                container.style.display = 'none';
+            }
+            return container;
+        },
+        _createAdvancedSearchFiltersAttributElement: function (filterAttributes) {
+            var container = null;
+            var name = filterAttributes.name;
+            var title = filterAttributes.title;
+            var description = filterAttributes.description;
+            var code = filterAttributes.code;
+            var value = filterAttributes.value;
+            var div = document.createElement('div');
+            div.className = 'GPflexInput';
+            var label = document.createElement('label');
+            label.className = 'GPadvancedSearchFilterLabel';
+            label.htmlFor = name;
+            label.title = description || title;
+            label.innerHTML = title;
+            div.appendChild(label);
+            var input = document.createElement('input');
+            input.id = name;
+            input.className = 'GPadvancedSearchFilterInput';
+            input.type = 'text';
+            input.name = name;
+            if (value) {
+                input.value = value;
+            }
+            div.appendChild(input);
+            container = document.getElementById(this._addUID(code));
+            if (container) {
+                container.appendChild(div);
+            } else {
+                container = div;
+            }
+            return container;
+        },
+        _createGeocodeResultsHeaderElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.className = 'GPpanelHeader';
+            var divTitle = document.createElement('div');
+            divTitle.className = 'GPpanelTitle';
+            divTitle.innerHTML = 'Résultats de la recherche';
+            container.appendChild(divTitle);
+            var divClose = document.createElement('div');
+            divClose.id = this._addUID('GPgeocodeResultsClose');
+            divClose.className = 'GPpanelClose';
+            divClose.title = 'Fermer la fenêtre de résultats';
+            if (divClose.addEventListener) {
+                divClose.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                }, false);
+            } else if (divClose.attachEvent) {
+                divClose.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                });
+            }
+            container.appendChild(divClose);
+            return container;
+        },
+        _createGeocodeResultsListElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.id = this._addUID('GPgeocodeResults');
+            if (container.addEventListener) {
+                container.addEventListener('click', function (e) {
+                    if (!e.ctrlKey) {
+                        document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                    }
+                    self.onGeocodedResultsItemClick(e);
+                }, false);
+            } else if (container.attachEvent) {
+                container.attachEvent('onclick', function (e) {
+                    if (!e.ctrlKey) {
+                        document.getElementById(self._addUID('GPgeocodeResultsList')).style.display = 'none';
+                    }
+                    self.onGeocodedResultsItemClick(e);
+                });
+            }
+            return container;
+        },
+        _createGeocodedLocationElement: function (location, id) {
+            var container = document.getElementById(this._addUID('GPgeocodeResults'));
+            var div = document.createElement('div');
+            div.id = this._addUID('GeocodedLocation_' + id);
+            div.className = 'GPautoCompleteProposal';
+            if (typeof location === 'string') {
+                div.innerHTML = location;
+            } else {
+                var places = location.placeAttributes;
+                if (places.freeform) {
+                    div.innerHTML = places.freeform;
+                } else if (places.postalCode) {
+                    div.innerHTML = places.postalCode + ' ' + places.commune;
+                } else if (places.cadastralParcel) {
+                    div.innerHTML = places.cadastralParcel;
+                } else {
+                    div.innerHTML = '...';
+                }
+            }
+            container.appendChild(div);
+        }
+    };
+    return SearchEngineDOM;
+}(CommonUtilsSelectorID);
+CommonControlsSearchEngineUtils = function () {
+    var SearchEngineUtils = {
+        advancedSearchFiltersByDefault: {
+            PositionOfInterest: [
+                {
+                    name: 'importance',
+                    title: 'Importance'
+                },
+                {
+                    name: 'nature',
+                    title: 'Nature'
+                },
+                {
+                    name: 'territory',
+                    title: 'Territoire'
+                },
+                {
+                    name: 'insee',
+                    title: 'Code INSEE'
+                },
+                {
+                    name: 'municipality',
+                    title: 'Ville'
+                },
+                {
+                    name: 'department',
+                    title: 'Département'
+                }
+            ],
+            StreetAddress: [
+                {
+                    name: 'territory',
+                    title: 'Territoire'
+                },
+                {
+                    name: 'insee',
+                    title: 'Code INSEE'
+                },
+                {
+                    name: 'municipality',
+                    title: 'Ville'
+                },
+                {
+                    name: 'department',
+                    title: 'Département'
+                }
+            ],
+            CadastralParcel: [
+                {
+                    name: 'department',
+                    title: 'Département',
+                    description: 'Numéro du département (ex: 01, 94)'
+                },
+                {
+                    name: 'commune',
+                    title: 'Code commune (INSEE)',
+                    description: 'Code commune (INSEE) : 3 chiffres (ex: 067)'
+                },
+                {
+                    name: 'absorbedCity',
+                    title: 'Commune absorbée',
+                    description: 'Commune absorbée : 3 chiffres (ex: 000, 001)'
+                },
+                {
+                    name: 'section',
+                    title: 'Section',
+                    description: 'Section : 2 caractères (ex: AA, 0D)'
+                },
+                {
+                    name: 'number',
+                    title: 'Numéro',
+                    description: 'Numéro de la parcelle : 4 chiffres (ex: 0041, 0250)'
+                }
+            ],
+            Administratif: [
+                {
+                    name: 'prefecture',
+                    title: 'Préfecture'
+                },
+                {
+                    name: 'inseeRegion',
+                    title: 'Code région (INSEE)'
+                },
+                {
+                    name: 'inseeDepartment',
+                    title: 'Code département (INSEE)'
+                },
+                {
+                    name: 'municipality',
+                    title: 'Ville'
+                }
+            ]
+        },
+        zoomToResultsByDefault: function (info) {
+            var zoom = 15;
+            var service = info.service;
+            var fields = info.fields;
+            var type = info.type;
+            var importance = {
+                1: 11,
+                2: 12,
+                3: 13,
+                4: 14,
+                5: 15,
+                6: 16,
+                7: 17,
+                8: 17
+            };
+            if (service === 'SuggestedLocation') {
+                if (type === 'PositionOfInterest') {
+                    zoom = importance[fields.classification];
+                }
+            }
+            if (service === 'DirectGeocodedLocation') {
+                if (type === 'PositionOfInterest') {
+                    zoom = importance[fields.importance] || 14;
+                }
+            }
+            if (type === 'StreetAddress') {
+                zoom = 17;
+            }
+            if (type === 'CadastralParcel') {
+                zoom = 17;
+            }
+            if (type === 'Administratif') {
+                zoom = 12;
+            }
+            return zoom;
+        }
+    };
+    return SearchEngineUtils;
+}();
+LeafletControlsSearchEngine = function (L, woodman, Gp, RightManagement, ID, SearchEngineDOM, SearchEngineUtils) {
+    var SearchEngine = L.Control.extend({
+        includes: SearchEngineDOM,
+        options: {
+            position: 'topleft',
+            collapsed: true,
+            displayInfo: true,
+            zoomTo: '',
+            resources: [],
+            displayAdvancedSearch: true,
+            advancedSearch: {},
+            geocodeOptions: {},
+            autocompleteOptions: {}
+        },
+        initialize: function (options) {
+            L.Util.setOptions(this, options);
+            this._uid = ID.generate();
+            this._inputContainer = null;
+            this._suggestedContainer = null;
+            this._suggestedLocations = [];
+            this._geocodedContainer = null;
+            this._geocodedLocations = [];
+            this._filterContainer = null;
+            this._currentGeocodingCode = null;
+            this._currentGeocodingLocation = null;
+            this._advancedSearchFilters = {};
+            this._advancedSearchCodes = [];
+            this._marker = null;
+            this._servicesRightManagement = {};
+            this._noRightManagement = false;
+            this._checkRightsManagement();
+        },
+        onAdd: function () {
+            this._initAdvancedSearchCodes();
+            this._initAdvancedSearchFilters();
+            var container = this._initLayout();
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            return container;
+        },
+        onRemove: function () {
+        },
+        _checkRightsManagement: function () {
+            if (!this.options.resources || this.options.resources.length === 0) {
+                this.options.resources = [
+                    'StreetAddress',
+                    'PositionOfInterest'
+                ];
+            }
+            var _opts = null;
+            var _res = [];
+            var _key = null;
+            _key = this.options.geocodeOptions.apiKey;
+            _opts = this.options.geocodeOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = this.options.resources || [
+                    'StreetAddress',
+                    'PositionOfInterest'
+                ];
+            }
+            var rightManagementGeocode = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['Geocode']
+            });
+            _key = this.options.autocompleteOptions.apiKey;
+            _opts = this.options.autocompleteOptions.filterOptions;
+            _res = _opts ? _opts.type : [];
+            if (!_res || _res.length === 0) {
+                _res = this.options.resources || [
+                    'StreetAddress',
+                    'PositionOfInterest'
+                ];
+            }
+            var rightManagementAutoComplete = RightManagement.check({
+                key: _key || this.options.apiKey,
+                resources: _res,
+                services: ['AutoCompletion']
+            });
+            if (!rightManagementGeocode && !rightManagementAutoComplete) {
+                this._noRightManagement = true;
+            }
+            if (rightManagementAutoComplete) {
+                this._servicesRightManagement['AutoCompletion'] = {};
+                this._servicesRightManagement['AutoCompletion']['resources'] = rightManagementAutoComplete['AutoCompletion'];
+                this._servicesRightManagement['AutoCompletion']['key'] = rightManagementAutoComplete['key'];
+            }
+            if (rightManagementGeocode) {
+                this._servicesRightManagement['Geocode'] = {};
+                this._servicesRightManagement['Geocode']['resources'] = rightManagementGeocode['Geocode'];
+                this._servicesRightManagement['Geocode']['key'] = rightManagementGeocode['key'];
+            }
+            if (!this.options.advancedSearch || Object.keys(this.options.advancedSearch).length === 0) {
+                var r = this._servicesRightManagement['Geocode']['resources'];
+                for (var i = 0; i < r.length; i++) {
+                    var code = r[i];
+                    this.options.advancedSearch[code] = [];
+                }
+            }
+        },
+        _initLayout: function () {
+            var container = this._createMainContainerElement();
+            var inputShow = this._createShowSearchEngineElement();
+            container.appendChild(inputShow);
+            if (!this.options.collapsed) {
+                inputShow.checked = 'true';
+            }
+            var picto = this._createShowSearchEnginePictoElement();
+            container.appendChild(picto);
+            var search = this._createSearchInputElement();
+            container.appendChild(search);
+            if (this.options.displayAdvancedSearch) {
+                var advancedShow = this._createShowAdvancedSearchElement();
+                container.appendChild(advancedShow);
+                var advancedPanel = this._createAdvancedSearchPanelElement();
+                var advancedHeader = this._createAdvancedSearchPanelHeaderElement();
+                var advancedForm = this._createAdvancedSearchPanelFormElement(this._advancedSearchCodes);
+                var advancedFormFilters = this._filterContainer = this._createAdvancedSearchFormFiltersElement();
+                this._setFilter(this._advancedSearchCodes[0].id);
+                var advancedFormInput = this._createAdvancedSearchFormInputElement();
+                advancedForm.appendChild(advancedFormFilters);
+                advancedForm.appendChild(advancedFormInput);
+                advancedPanel.appendChild(advancedHeader);
+                advancedPanel.appendChild(advancedForm);
+                container.appendChild(advancedPanel);
+            }
+            var autocomplete = this._createAutoCompleteElement();
+            var autocompleteList = this._suggestedContainer = this._createAutoCompleteListElement();
+            autocomplete.appendChild(autocompleteList);
+            container.appendChild(autocomplete);
+            var geocode = this._createGeocodeResultsElement();
+            var geocodeList = this._geocodedContainer = this._createGeocodeResultsListElement();
+            geocode.appendChild(geocodeList);
+            container.appendChild(geocode);
+            return container;
+        },
+        _initAdvancedSearchCodes: function () {
+            var advancedSearchCodesByDefault = [
+                {
+                    id: 'PositionOfInterest',
+                    title: 'Lieux/toponymes'
+                },
+                {
+                    id: 'StreetAddress',
+                    title: 'Adresses'
+                },
+                {
+                    id: 'CadastralParcel',
+                    title: 'Parcelles cadastrales'
+                },
+                {
+                    id: 'Administratif',
+                    title: 'Administratif'
+                }
+            ];
+            var _resources = Object.keys(this.options.advancedSearch);
+            for (var i = 0; i < _resources.length; i++) {
+                var id = _resources[i];
+                for (var j = 0; j < advancedSearchCodesByDefault.length; j++) {
+                    if (advancedSearchCodesByDefault[j].id === id) {
+                        this._advancedSearchCodes.push(advancedSearchCodesByDefault[j]);
+                    }
+                }
+            }
+            if (this._advancedSearchCodes.length === 0) {
+                this._advancedSearchCodes = advancedSearchCodesByDefault;
+            }
+        },
+        _initAdvancedSearchFilters: function () {
+            var advancedSearchFiltersByDefault = {
+                PositionOfInterest: [
+                    {
+                        name: 'city',
+                        title: 'Ville',
+                        filter: false,
+                        sep: true
+                    },
+                    {
+                        name: 'importance',
+                        title: 'Importance',
+                        filter: true
+                    },
+                    {
+                        name: 'nature',
+                        title: 'Nature',
+                        filter: true
+                    },
+                    {
+                        name: 'territory',
+                        title: 'Territoire',
+                        filter: true
+                    },
+                    {
+                        name: 'insee',
+                        title: 'Code commune (INSEE)',
+                        filter: true
+                    },
+                    {
+                        name: 'department',
+                        title: 'Département',
+                        filter: true
+                    }
+                ],
+                StreetAddress: [
+                    {
+                        name: 'number',
+                        title: 'Numéro',
+                        filter: false,
+                        sep: true
+                    },
+                    {
+                        name: 'street',
+                        title: 'Rue',
+                        filter: false,
+                        sep: true
+                    },
+                    {
+                        name: 'postalCode',
+                        title: 'Code Postal',
+                        filter: false,
+                        sep: true
+                    },
+                    {
+                        name: 'city',
+                        title: 'Ville',
+                        filter: false,
+                        sep: true
+                    },
+                    {
+                        name: 'territory',
+                        title: 'Territoire',
+                        filter: true
+                    },
+                    {
+                        name: 'insee',
+                        title: 'Code commune (INSEE)',
+                        filter: true
+                    },
+                    {
+                        name: 'department',
+                        title: 'Département',
+                        filter: true
+                    }
+                ],
+                CadastralParcel: [
+                    {
+                        name: 'department',
+                        title: 'Département',
+                        filter: false,
+                        sep: false,
+                        value: '__'
+                    },
+                    {
+                        name: 'commune',
+                        title: 'Commune',
+                        filter: false,
+                        sep: false,
+                        value: '___'
+                    },
+                    {
+                        name: 'absorbedCity',
+                        title: 'Commune absorbée',
+                        filter: false,
+                        sep: false,
+                        value: '___'
+                    },
+                    {
+                        name: 'section',
+                        title: 'Section',
+                        filter: false,
+                        sep: false,
+                        value: '__'
+                    },
+                    {
+                        name: 'number',
+                        title: 'Numéro',
+                        filter: false,
+                        sep: false,
+                        value: '____'
+                    }
+                ],
+                Administratif: [
+                    {
+                        name: 'prefecture',
+                        title: 'Préfecture',
+                        filter: true
+                    },
+                    {
+                        name: 'inseeRegion',
+                        title: 'Code région (INSEE)',
+                        filter: true
+                    },
+                    {
+                        name: 'inseeDepartment',
+                        title: 'Code département (INSEE)',
+                        filter: true
+                    },
+                    {
+                        name: 'city',
+                        title: 'Ville',
+                        filter: false,
+                        sep: true
+                    }
+                ]
+            };
+            var advancedSearchFiltersCustom = this.options.advancedSearch;
+            for (var code in advancedSearchFiltersCustom) {
+                if (advancedSearchFiltersCustom.hasOwnProperty(code)) {
+                    if (!advancedSearchFiltersCustom[code] || advancedSearchFiltersCustom[code].length === 0) {
+                        advancedSearchFiltersCustom[code] = advancedSearchFiltersByDefault[code];
+                        continue;
+                    }
+                    var filters = advancedSearchFiltersCustom[code];
+                    for (var i = 0; i < filters.length; i++) {
+                        var o = filters[i];
+                        if (!o.hasOwnProperty('filter')) {
+                            o.filter = o.name === 'municipality' ? false : true;
+                        }
+                    }
+                }
+            }
+            L.Util.extend(this._advancedSearchFilters, advancedSearchFiltersByDefault, advancedSearchFiltersCustom);
+        },
+        _setFilter: function (code) {
+            var container = this._filterContainer;
+            var codeFound = false;
+            for (var i = 0; i < this._advancedSearchCodes.length; i++) {
+                if (this._advancedSearchCodes[i].id === code) {
+                    codeFound = true;
+                    break;
+                }
+            }
+            if (!codeFound) {
+                while (container.firstChild) {
+                    container.removeChild(container.firstChild);
+                }
+                return;
+            }
+            this._currentGeocodingCode = code;
+            while (container.firstChild) {
+                container.removeChild(container.firstChild);
+            }
+            var lstAttributs = this._advancedSearchFilters[code];
+            if (!lstAttributs || lstAttributs.length === 0) {
+                return;
+            }
+            var divTable = this._createAdvancedSearchFiltersTableElement(code, true);
+            for (var j = 0; j < lstAttributs.length; j++) {
+                var divFilter = this._createAdvancedSearchFiltersAttributElement(lstAttributs[j]);
+                divTable.appendChild(divFilter);
+            }
+            container.appendChild(divTable);
+            return container;
+        },
+        _requestAutoComplete: function (settings) {
+            if (!settings || Object.keys(settings).length === 0) {
+                return;
+            }
+            if (!settings.text) {
+                return;
+            }
+            if (this._noRightManagement) {
+                console.log('no rights for all service !?');
+                return;
+            }
+            if (!this._servicesRightManagement['AutoCompletion']) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            var options = {};
+            L.Util.extend(options, this.options.autocompleteOptions);
+            L.Util.extend(options, settings);
+            var resources = this._servicesRightManagement['AutoCompletion'].resources;
+            if (!resources || Object.keys(resources).length === 0) {
+                return;
+            }
+            if (resources && L.Util.isArray(resources) && !options.filterOptions) {
+                if (!options.filterOptions) {
+                    options.filterOptions = {};
+                }
+                options.filterOptions.type = resources;
+            }
+            var key = this._servicesRightManagement['AutoCompletion']['key'];
+            L.Util.extend(options, { apiKey: options.apiKey || this.options.apiKey || key });
+            Gp.Services.autoComplete(options);
+        },
+        _fillAutoCompletedLocationListContainer: function (locations) {
+            if (!locations || locations.length === 0) {
+                return;
+            }
+            var element = this._suggestedContainer;
+            if (element.childElementCount) {
+                while (element.firstChild) {
+                    element.removeChild(element.firstChild);
+                }
+            }
+            for (var i = 0; i < locations.length; i++) {
+                this._createAutoCompletedLocationElement(locations[i], i);
+            }
+            this._suggestedLocations = locations;
+        },
+        _requestGeocoding: function (settings) {
+            if (!settings || Object.keys(settings).length === 0) {
+                return;
+            }
+            if (!settings.location) {
+                return;
+            }
+            if (this._noRightManagement) {
+                console.log('no rights for all service !?');
+                return;
+            }
+            if (!this._servicesRightManagement['Geocode']) {
+                console.log('no rights for this service !?');
+                return;
+            }
+            var options = {};
+            L.Util.extend(options, this.options.geocodeOptions);
+            L.Util.extend(options, settings);
+            if (!options.hasOwnProperty('returnFreeForm')) {
+                L.Util.extend(options, { returnFreeForm: false });
+            }
+            var resources = this._servicesRightManagement['Geocode'].resources;
+            if (!resources || Object.keys(resources).length === 0) {
+                return;
+            }
+            if (resources && L.Util.isArray(resources) && !options.filterOptions) {
+                if (!options.filterOptions) {
+                    options.filterOptions = {};
+                }
+                options.filterOptions.type = resources;
+            }
+            var key = this._servicesRightManagement['Geocode']['key'];
+            L.Util.extend(options, { apiKey: options.apiKey || this.options.apiKey || key });
+            Gp.Services.geocode(options);
+        },
+        _fillGeocodedLocationListContainer: function (locations) {
+            if (!locations || locations.length === 0) {
+                this._clearGeocodedLocation();
+                return;
+            }
+            var element = this._geocodedContainer;
+            if (element.childElementCount) {
+                while (element.firstChild) {
+                    element.removeChild(element.firstChild);
+                }
+            }
+            for (var i = 0; i < locations.length; i++) {
+                this._createGeocodedLocationElement(locations[i], i);
+            }
+            this._geocodedLocations = locations;
+        },
+        _setLabel: function (label) {
+            var element = L.DomUtil.get('GPsearchInputText-' + this._uid);
+            element.value = label || '';
+        },
+        _setPosition: function (position, zoom) {
+            var map = this._map;
+            map.setZoomAround(L.latLng(position.x, position.y), zoom, true);
+            map.panTo(L.latLng(position.x, position.y));
+        },
+        _getZoom: function (info) {
+            var map = this._map;
+            var key = this.options.zoomTo;
+            var zoom = null;
+            if (typeof key === 'function') {
+                zoom = key.call(this, info);
+            }
+            if (typeof key === 'number') {
+                zoom = key;
+            }
+            if (typeof key === 'string') {
+                if (key === 'auto') {
+                    zoom = SearchEngineUtils.zoomToResultsByDefault(info);
+                } else {
+                    var value = parseInt(key, 10);
+                    if (!isNaN(value)) {
+                        zoom = value;
+                    }
+                }
+            }
+            Number.isInteger = Number.isInteger || function (value) {
+                return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
+            };
+            if (!zoom || zoom === '' || !Number.isInteger(zoom)) {
+                zoom = map.getZoom();
+            }
+            var min = map.getMinZoom();
+            var max = map.getMaxZoom();
+            if (zoom < min) {
+                zoom = min;
+            }
+            if (zoom > max) {
+                zoom = max;
+            }
+            return zoom;
+        },
+        _setMarker: function (position, information, display) {
+            var map = this._map;
+            if (this._marker != null) {
+                map.removeLayer(this._marker);
+                this._marker = null;
+            }
+            if (position) {
+                var options = {
+                    clickable: true,
+                    zIndexOffset: 1000
+                };
+                this._marker = L.marker(L.latLng(position.x, position.y), options);
+                this._marker.addTo(map);
+                if (display) {
+                    var popupContent = null;
+                    if (typeof information !== 'string') {
+                        var values = [];
+                        if (information.service === 'DirectGeocodedLocation') {
+                            if (information.fields.freeform) {
+                                popupContent = information.fields.freeform;
+                            } else {
+                                var attributs = this._advancedSearchFilters[information.type];
+                                for (var i = 0; i < attributs.length; i++) {
+                                    var key = attributs[i].name;
+                                    var value = information.fields[key];
+                                    if (typeof value === 'string' || typeof value === 'number') {
+                                        values.push(value);
+                                    }
+                                }
+                                popupContent = values.join(' - ');
+                            }
+                        } else if (information.service === 'SuggestedLocation') {
+                            if (information.fields.fullText) {
+                                popupContent = information.fields.fullText;
+                            } else {
+                                values.push(information.fields.street || '');
+                                values.push(information.fields.postalCode || '');
+                                values.push(information.fields.commune || '');
+                                if (information.type === 'PositionOfInterest') {
+                                    values.push(information.fields.poi || '');
+                                    values.push(information.fields.kind || '');
+                                }
+                                popupContent = values.join(' - ');
+                            }
+                        } else {
+                            popupContent = 'sans informations.';
+                        }
+                    } else {
+                        popupContent = information;
+                    }
+                    this._marker.bindPopup(popupContent);
+                }
+            }
+        },
+        _clearResults: function () {
+            this._currentGeocodingLocation = null;
+            this._clearSuggestedLocation();
+            this._clearGeocodedLocation();
+            this._setMarker();
+        },
+        _clearSuggestedLocation: function () {
+            this._suggestedLocations = [];
+            if (this._suggestedContainer) {
+                while (this._suggestedContainer.firstChild) {
+                    this._suggestedContainer.removeChild(this._suggestedContainer.firstChild);
+                }
+            }
+        },
+        _clearGeocodedLocation: function () {
+            this._geocodedLocations = [];
+            if (this._geocodedContainer) {
+                while (this._geocodedContainer.firstChild) {
+                    this._geocodedContainer.removeChild(this._geocodedContainer.firstChild);
+                }
+            }
+        },
+        onShowSearchEngineClick: function () {
+        },
+        onSearchResetClick: function () {
+            this._clearResults();
+        },
+        onAutoCompleteSearchText: function (e) {
+            var value = e.target.value;
+            if (!value) {
+                return;
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            this._currentGeocodingLocation = value;
+            if (value.length < 3) {
+                return;
+            }
+            var context = this;
+            this._requestAutoComplete({
+                text: value,
+                onSuccess: function (results) {
+                    if (results) {
+                        var locations = results.suggestedLocations;
+                        context._fillAutoCompletedLocationListContainer(locations);
+                    }
+                },
+                onFailure: function (error) {
+                    context._clearSuggestedLocation();
+                }
+            });
+        },
+        onAutoCompletedResultsItemClick: function (e) {
+            var idx = ID.index(e.target.id);
+            var label = e.target.innerHTML;
+            if (!idx) {
+                return;
+            }
+            var position = {
+                x: this._suggestedLocations[idx].position.y,
+                y: this._suggestedLocations[idx].position.x
+            };
+            var info = {
+                service: 'SuggestedLocation',
+                type: this._suggestedLocations[idx].type,
+                fields: this._suggestedLocations[idx]
+            };
+            var zoom = this._getZoom(info);
+            this._setLabel(label);
+            this._setPosition(position, zoom);
+            this._setMarker(position, info, this.options.displayInfo);
+        },
+        onGeocodingSearchSubmit: function (e) {
+            var value = e.target[0].value;
+            if (!value) {
+                return;
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            this._currentGeocodingLocation = value;
+            var context = this;
+            this._requestGeocoding({
+                location: value,
+                onSuccess: function (results) {
+                    if (results) {
+                        var locations = results.locations;
+                        context._fillGeocodedLocationListContainer(locations);
+                    }
+                },
+                onFailure: function (error) {
+                    context._clearGeocodedLocation();
+                }
+            });
+        },
+        onGeocodedResultsItemClick: function (e) {
+            var idx = ID.index(e.target.id);
+            var label = e.target.innerHTML;
+            if (!idx) {
+                return;
+            }
+            var position = this._geocodedLocations[idx].position;
+            var info = {
+                service: 'DirectGeocodedLocation',
+                type: this._geocodedLocations[idx].type,
+                fields: this._geocodedLocations[idx].placeAttributes
+            };
+            var zoom = this._getZoom(info);
+            this._setLabel(label);
+            this._setPosition(position, zoom);
+            this._setMarker(position, info, this.options.displayInfo);
+        },
+        onGeocodingAdvancedSearchCodeChange: function (e) {
+            var idx = e.target.selectedIndex;
+            var value = e.target.options[idx].value;
+            if (!value) {
+                return;
+            }
+            this._setFilter(value);
+        },
+        onGeocodingAdvancedSearchSubmit: function (e, data) {
+            if (!data || data.length === 0) {
+                return;
+            }
+            var _filterOptions = {};
+            _filterOptions['type'] = [this._currentGeocodingCode];
+            var _location = this._currentGeocodingLocation || '';
+            if (this._currentGeocodingCode === 'CadastralParcel') {
+                _location = '';
+            }
+            for (var i = 0; i < data.length; i++) {
+                var filter = data[i];
+                if (!filter.value) {
+                    continue;
+                }
+                var filters = this._advancedSearchFilters[this._currentGeocodingCode];
+                for (var j = 0; j < filters.length; j++) {
+                    var o = filters[j];
+                    if (o.name === filter.key) {
+                        if (o.filter) {
+                            _filterOptions[filter.key] = filter.value;
+                        } else {
+                            if (o.value) {
+                                var cur = filter.value.length;
+                                var max = o.value.length;
+                                if (max !== cur) {
+                                    var masked = max - cur;
+                                    var filler = o.value.charAt(0);
+                                    while (filler.length < masked) {
+                                        filler += filler;
+                                    }
+                                    var fillerSlice = filler.slice(0, masked);
+                                    filter.value = filter.value + fillerSlice;
+                                }
+                                _location += filter.value;
+                            } else {
+                                if (typeof _location === 'string') {
+                                    _location = {};
+                                }
+                                _location[filter.key] = filter.value;
+                            }
+                        }
+                    }
+                }
+            }
+            var context = this;
+            this._requestGeocoding({
+                location: _location,
+                filterOptions: _filterOptions,
+                onSuccess: function (results) {
+                    if (results) {
+                        var locations = results.locations;
+                        context._fillGeocodedLocationListContainer(locations);
+                    }
+                },
+                onFailure: function (error) {
+                    context._clearGeocodedLocation();
+                }
+            });
+        }
+    });
+    return SearchEngine;
+}(leaflet, {}, gp, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, CommonControlsSearchEngineDOM, CommonControlsSearchEngineUtils);
+CommonControlsElevationPathDOM = function () {
+    var ElevationPathDOM = {
+        _addUID: function (id) {
+            return id + '-' + this._uid;
+        },
+        _createMainContainerElement: function () {
+            var container = document.createElement('div');
+            container.id = this._addUID('GPelevationPath');
+            container.className = 'GPwidget';
+            return container;
+        },
+        _createShowElevationPathElement: function () {
+            var input = document.createElement('input');
+            input.id = this._addUID('GPshowElevationPath');
+            input.type = 'checkbox';
+            return input;
+        },
+        _createShowElevationPathPictoElement: function () {
+            var context = this;
+            var label = document.createElement('label');
+            label.id = this._addUID('GPshowElevationPathPicto');
+            label.className = 'GPshowAdvancedToolPicto';
+            label.htmlFor = this._addUID('GPshowElevationPath');
+            label.title = 'Calculer un profil';
+            if (label.addEventListener) {
+                label.addEventListener('click', function (e) {
+                    context.onShowElevationPathClick(e);
+                });
+            } else if (label.attachEvent) {
+                label.attachEvent('onclick', function (e) {
+                    context.onShowElevationPathClick(e);
+                });
+            }
+            var spanOpen = document.createElement('span');
+            spanOpen.id = this._addUID('GPshowElevationPathOpen');
+            spanOpen.className = 'GPshowAdvancedToolOpen';
+            label.appendChild(spanOpen);
+            return label;
+        },
+        _createElevationPathPanelElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPelevationPathPanel');
+            div.className = 'GPpanel';
+            return div;
+        },
+        _createElevationPathPanelHeaderElement: function () {
+            var self = this;
+            var container = document.createElement('div');
+            container.className = 'GPpanelHeader';
+            var div = document.createElement('div');
+            div.className = 'GPpanelTitle';
+            div.innerHTML = 'Profil Altimétrique';
+            container.appendChild(div);
+            var divReduce = document.createElement('div');
+            divReduce.id = this._addUID('GPelevationPathPanelReduce');
+            divReduce.className = 'GPpanelReduce';
+            divReduce.title = 'Masquer le panneau';
+            if (divReduce.addEventListener) {
+                divReduce.addEventListener('click', function () {
+                    if (typeof self.onReduceElevationPathPanelClick === 'function') {
+                        document.getElementById(self._addUID('GPshowElevationPath')).checked = false;
+                        self.onReduceElevationPathPanelClick();
+                    }
+                }, false);
+            } else if (divReduce.attachEvent) {
+                divReduce.attachEvent('onclick', function () {
+                    if (typeof self.onReduceElevationPathPanelClick === 'function') {
+                        document.getElementById(self._addUID('GPshowElevationPath')).checked = false;
+                        self.onReduceElevationPathPanelClick();
+                    }
+                });
+            }
+            container.appendChild(divReduce);
+            var divClose = document.createElement('div');
+            divClose.id = this._addUID('GPelevationPathPanelClose');
+            divClose.className = 'GPpanelClose';
+            divClose.title = 'Fermer le panneau';
+            if (divClose.addEventListener) {
+                divClose.addEventListener('click', function () {
+                    document.getElementById(self._addUID('GPshowElevationPathPicto')).click();
+                }, false);
+            } else if (divClose.attachEvent) {
+                divClose.attachEvent('onclick', function () {
+                    document.getElementById(self._addUID('GPshowElevationPathPicto')).click();
+                });
+            }
+            container.appendChild(divClose);
+            return container;
+        },
+        _createElevationPathPanelProfilElement: function () {
+            var div = document.createElement('div');
+            div.id = 'GPelevationPathProfil';
+            return div;
+        },
+        _createElevationPathWaitingElement: function () {
+            var div = document.createElement('div');
+            div.id = this._addUID('GPelevationPathCalcWaitingContainer');
+            div.className = 'GPelevationPathCalcWaitingContainerHidden';
+            var p = document.createElement('p');
+            p.className = 'GPelevationPathCalcWaiting';
+            p.innerHTML = 'Calcul en cours...';
+            div.appendChild(p);
+            return div;
+        }
+    };
+    return ElevationPathDOM;
+}();
+LeafletControlsElevationPath = function (L, P, woodman, Gp, RightManagement, ID, LocationSelector, PositionFormater, IconDefault, ElevationPathDOM) {
+    var ElevationPath = L.Control.extend({
+        includes: ElevationPathDOM,
+        options: {
+            position: 'topleft',
+            active: false,
+            elevationPathOptions: {},
+            stylesOptions: {},
+            displayProfileOptions: {
+                apply: null,
+                target: null
+            }
+        },
+        initialize: function (options) {
+            L.Util.setOptions(this, options);
+            this._uid = ID.generate();
+            this._initDisplayProfileOptions();
+            this._showContainer = null;
+            this._pictoContainer = null;
+            this._panelContainer = null;
+            this._profilContainer = null;
+            this._waitingContainer = null;
+            this._reducePanel = false;
+            this._featuresLayer = null;
+            this._lastIdLayer = 0;
+            this._currentIdLayer = 0;
+            this._currentFeature = null;
+            this._profile = null;
+            this._marker = null;
+            this._geometry = null;
+            this._noRightManagement = false;
+            this._checkRightsManagement();
+        },
+        onAdd: function (map) {
+            var container = this._container = this._initLayout();
+            if (map) {
+                if (this.options.active) {
+                    if (this._profile === null) {
+                        this._panelContainer.style.display = 'none';
+                    }
+                    this._activateMapInteraction(map);
+                }
+            }
+            L.DomEvent.disableClickPropagation(container).disableScrollPropagation(container);
+            return container;
+        },
+        onRemove: function () {
+        },
+        _checkRightsManagement: function () {
+            var rightManagement = RightManagement.check({
+                key: this.options.apiKey,
+                resources: ['SERVICE_CALCUL_ALTIMETRIQUE_RSC'],
+                services: ['ElevationLine']
+            });
+            if (!rightManagement) {
+                this._noRightManagement = true;
+            }
+            if (!this.options.apiKey) {
+                this.options.apiKey = rightManagement.key;
+            }
+        },
+        _initDisplayProfileOptions: function () {
+            var profil = this.options.displayProfileOptions || {};
+            if (typeof profil === 'undefined' || Object.keys(profil).length === 0) {
+                this.options.displayProfileOptions = {
+                    apply: ElevationPath.DISPLAY_PROFILE_BY_DEFAULT,
+                    target: null
+                };
+            } else {
+                this.options.displayProfileOptions = {};
+            }
+            var displayFunction = profil.apply || this.options.displayProfileOptions.apply;
+            this.options.displayProfileOptions.apply = typeof displayFunction === 'function' ? displayFunction : ElevationPath.DISPLAY_PROFILE_BY_DEFAULT;
+            var displayContainer = profil.target || this.options.displayProfileOptions.target;
+            this.options.displayProfileOptions.target = typeof displayContainer === 'undefined' ? null : displayContainer;
+        },
+        _initLayout: function () {
+            var container = this._createMainContainerElement();
+            var inputShow = this._showContainer = this._createShowElevationPathElement();
+            container.appendChild(inputShow);
+            if (this.options.active) {
+                this._showContainer.checked = true;
+            }
+            var picto = this._pictoContainer = this._createShowElevationPathPictoElement();
+            container.appendChild(picto);
+            var panel = this._panelContainer = this._createElevationPathPanelElement();
+            var header = this._createElevationPathPanelHeaderElement();
+            panel.appendChild(header);
+            var profil = this._profilContainer = this._createElevationPathPanelProfilElement();
+            panel.appendChild(profil);
+            var waiting = this._waitingContainer = this._createElevationPathWaitingElement();
+            panel.appendChild(waiting);
+            container.appendChild(panel);
+            return container;
+        },
+        onShowElevationPathClick: function (e) {
+            var map = this._map;
+            if (!this._reducePanel) {
+                if (this._showContainer.checked) {
+                    this._pictoContainer.style.display = 'block';
+                    this._panelContainer.style.display = 'none';
+                    this._removeMapInteraction(map);
+                    this._clear();
+                } else {
+                    if (this._profile === null) {
+                        this._panelContainer.style.display = 'none';
+                    }
+                    this._activateMapInteraction(map);
+                }
+            } else {
+                if (this._profile !== null) {
+                    if (this.options.displayProfileOptions.target === null) {
+                        this._pictoContainer.style.display = 'none';
+                    }
+                    this._panelContainer.style.display = 'block';
+                }
+            }
+            this._reducePanel = false;
+        },
+        onReduceElevationPathPanelClick: function () {
+            this._reducePanel = true;
+            this._pictoContainer.style.display = 'block';
+            this._panelContainer.style.display = 'none';
+        },
+        _activateMapInteraction: function (map) {
+            if (this._featuresLayer === null) {
+                this._featuresLayer = new L.FeatureGroup();
+                map.addLayer(this._featuresLayer);
+                var self = this;
+                map.on('draw:created', function (e) {
+                    self._currentIdLayer = L.Util.stamp(e.layer);
+                    self._getFeatureGeometry(e.layer);
+                    self._addFeatureLayer(e.layer);
+                });
+                map.on('draw:drawstart', function () {
+                    self._removeFeatureLayer(self._lastIdLayer);
+                    self._lastIdLayer = self._currentIdLayer;
+                });
+                map.on('draw:drawstop', function () {
+                    if (typeof self.options.elevationPathOptions.onSuccess === 'undefined' && self.options.displayProfileOptions.target === null) {
+                        self._pictoContainer.style.display = 'none';
+                        self._panelContainer.style.display = 'block';
+                    }
+                    self._altiRequest();
+                });
+            }
+            this._activatePolyLineInteraction(map);
+        },
+        _removeMapInteraction: function (map) {
+            if (!map) {
+                return;
+            }
+            if (this._featuresLayer !== null) {
+                map.off('draw:created');
+                map.off('draw:drawstart');
+                map.off('draw:drawstop');
+                map.removeLayer(this._featuresLayer);
+                this._featuresLayer = null;
+            }
+            this._lastIdLayer = this._currentIdLayer = 0;
+            if (this._currentFeature) {
+                this._currentFeature.disable();
+            }
+        },
+        _activatePolyLineInteraction: function (map) {
+            if (this._currentFeature) {
+                this._currentFeature.disable();
+            }
+            var styles = this.options.stylesOptions || {};
+            var _shapeOptions = Object.keys(styles).length !== 0 ? styles : {
+                stroke: true,
+                color: '#C77A04',
+                weight: 4,
+                opacity: 0.5,
+                fill: false
+            };
+            this._currentFeature = new L.Draw.Polyline(map, { shapeOptions: _shapeOptions });
+            this._currentFeature.enable();
+        },
+        _getFeatureGeometry: function (layer) {
+            if (this._geometry !== null) {
+                this._geometry = null;
+            }
+            this._geometry = [];
+            var geometry = layer.getLatLngs();
+            for (var i = 0; i < geometry.length; i++) {
+                var LatLng = geometry[i];
+                this._geometry.push({
+                    lon: LatLng.lng,
+                    lat: LatLng.lat
+                });
+            }
+        },
+        _addFeatureLayer: function (layer) {
+            if (!this._featuresLayer) {
+                return;
+            }
+            this._featuresLayer.addLayer(layer);
+        },
+        _removeFeatureLayer: function (id) {
+            if (!this._featuresLayer) {
+                return;
+            }
+            if (id === 0) {
+                return;
+            }
+            if (!id) {
+                this._featuresLayer.clearLayers();
+            } else {
+                this._featuresLayer.removeLayer(id);
+            }
+        },
+        _altiRequest: function () {
+            if (!this._geometry) {
+                return;
+            }
+            if (this._noRightManagement) {
+                return;
+            }
+            var options = {};
+            L.Util.extend(options, this.options.elevationPathOptions);
+            L.Util.extend(options, { apiKey: options.apiKey || this.options.apiKey });
+            var self = this;
+            L.Util.extend(options, {
+                sampling: options.sampling || 200,
+                onSuccess: this.options.elevationPathOptions.onSuccess || function (result) {
+                    if (result) {
+                        if (self.options.displayProfileOptions.target !== null) {
+                            self._pictoContainer.style.display = 'block';
+                            self._panelContainer.style.display = 'block';
+                        }
+                        self._displayProfil(result.elevations);
+                        self._waitingContainer.className = 'GPelevationPathCalcWaitingContainerHidden';
+                        self._waiting = false;
+                    }
+                },
+                onFailure: this.options.elevationPathOptions.onFailure || function (error) {
+                    self._pictoContainer.style.display = 'block';
+                    self._panelContainer.style.display = 'none';
+                    self._waitingContainer.className = 'GPelevationPathCalcWaitingContainerHidden';
+                    self._waiting = false;
+                    self._clear();
+                }
+            });
+            var positions = this._geometry;
+            L.Util.extend(options, { positions: positions });
+            this._waitingContainer.className = 'GPelevationPathCalcWaitingContainerVisible';
+            Gp.Services.getAltitude(options);
+        },
+        _computeElevationMeasure: function (elevations) {
+            var _haversineDistance = function (c1, c2) {
+                var lat1 = PositionFormater.decimalToRadian(c1[1]);
+                var lat2 = PositionFormater.decimalToRadian(c2[1]);
+                var deltaLatBy2 = (lat2 - lat1) / 2;
+                var deltaLonBy2 = PositionFormater.decimalToRadian(c2[0] - c1[0]) / 2;
+                var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) + Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) * Math.cos(lat1) * Math.cos(lat2);
+                return 2 * 6378137 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+            };
+            elevations[0].dist = 0;
+            var distance = 0;
+            for (var i = 1; i < elevations.length; i++) {
+                distance += _haversineDistance([
+                    elevations[i].lon,
+                    elevations[i].lat
+                ], [
+                    elevations[i - 1].lon,
+                    elevations[i - 1].lat
+                ]) / 1000;
+                elevations[i].dist = distance;
+                elevations[i].lat = Math.round(elevations[i].lat * 10000) / 10000;
+                elevations[i].lon = Math.round(elevations[i].lon * 10000) / 10000;
+            }
+            var coeffArrond = 100;
+            if (distance > 100) {
+                coeffArrond = 1;
+            } else if (distance > 10) {
+                coeffArrond = 10;
+            }
+            for (var j = 0; j < elevations.length; j++) {
+                var data = elevations[j];
+                if (data.z < 0) {
+                    data.z = 0;
+                }
+                data.dist = Math.round(data.dist * coeffArrond) / coeffArrond;
+            }
+            return elevations;
+        },
+        _displayProfil: function (elevations) {
+            var data = this._computeElevationMeasure(elevations);
+            var container = this.options.displayProfileOptions.target;
+            if (container) {
+                container.appendChild(this._panelContainer);
+            }
+            container = this._profilContainer;
+            var context = this;
+            var displayFunction = this.options.displayProfileOptions.apply;
+            if (typeof AmCharts !== 'undefined' && typeof d3 !== 'undefined') {
+            }
+            displayFunction.call(this, data, container, context);
+        },
+        _activateProfilEvent: function (position) {
+            if (this._profile === null) {
+                return;
+            }
+            var map = this._map;
+            var self = this;
+            if (self._marker) {
+                map.removeLayer(self._marker);
+                self._marker = null;
+            }
+            self._marker = L.marker(L.latLng(position.lat, position.lon), {
+                icon: new IconDefault('orange'),
+                draggable: false,
+                clickable: false,
+                zIndexOffset: 1000
+            });
+            self._marker.addTo(map);
+            var changed = function (e) {
+                var obj = e.chart.dataProvider[e.index];
+                self._marker.setLatLng(L.latLng(obj.lat, obj.lon));
+                self._marker.update();
+            };
+            self._profile.removeListener('changed', changed);
+            self._profile.addListener('changed', changed);
+            var mouseover = function (e) {
+                if (self._profile === null) {
+                    return;
+                }
+                self._marker = L.marker(L.latLng(position.lat, position.lon), {
+                    icon: new IconDefault('orange'),
+                    draggable: false,
+                    clickable: false,
+                    zIndexOffset: 1000
+                });
+                self._marker.addTo(map);
+            };
+            var mouseout = function (e) {
+                if (self._profile === null) {
+                    return;
+                }
+                if (self._marker) {
+                    map.removeLayer(self._marker);
+                    self._marker = null;
+                }
+            };
+            var mousemove = function (e) {
+                if (self._profile === null) {
+                    return;
+                }
+                if (self._marker) {
+                    self._marker.setLatLng(L.latLng(e.lat, e.lon));
+                    self._marker.update();
+                }
+            };
+        },
+        _clear: function () {
+            this._geometry = null;
+            this._profile = null;
+            if (this._profilContainer) {
+                while (this._profilContainer.firstChild) {
+                    this._profilContainer.removeChild(this._profilContainer.firstChild);
+                }
+            }
+            var map = this._map;
+            if (this._marker) {
+                map.removeLayer(this._marker);
+                this._marker = null;
+            }
+        }
+    });
+    ElevationPath.DISPLAY_PROFILE_BY_DEFAULT = function (data, container, context) {
+        if (container) {
+            while (container.firstChild) {
+                container.removeChild(container.firstChild);
+            }
+        }
+        if (!data) {
+            return;
+        }
+        var sortedElev = JSON.parse(JSON.stringify(data));
+        sortedElev.sort(function (e1, e2) {
+            return e1.z - e2.z;
+        });
+        var minZ = sortedElev[0].z;
+        var maxZ = sortedElev[sortedElev.length - 1].z;
+        var diff = maxZ - minZ;
+        var dist = data[data.length - 1].dist;
+        var barwidth = 100 / data.length;
+        var self = this;
+        var map = context._map;
+        var div = document.createElement('div');
+        div.id = 'profileElevationByDefault';
+        div.addEventListener('mouseover', function (e) {
+            var _lon = parseFloat(e.target.dataset['lon']);
+            var _lat = parseFloat(e.target.dataset['lat']);
+            if (_lon && _lat) {
+                self._marker = L.marker(L.latLng(_lat, _lon), {
+                    icon: new IconDefault('orange'),
+                    draggable: false,
+                    clickable: false,
+                    zIndexOffset: 1000
+                });
+                self._marker.addTo(map);
+            }
+        });
+        div.addEventListener('mousemove', function () {
+        });
+        div.addEventListener('mouseout', function () {
+            if (self._marker) {
+                map.removeLayer(self._marker);
+                self._marker = null;
+            }
+        });
+        container.appendChild(div);
+        var divZ = document.createElement('div');
+        divZ.className = 'z-title-vertical';
+        divZ.innerHTML = minZ + ' / ' + maxZ + ' m';
+        div.appendChild(divZ);
+        var ul = document.createElement('ul');
+        ul.id = 'data-default';
+        ul.className = 'z-axis x-axis';
+        div.appendChild(ul);
+        for (var i = 0; i < data.length; i++) {
+            var d = data[i];
+            var li = document.createElement('li');
+            li.setAttribute('data-z', d.z);
+            li.setAttribute('data-lon', d.lon);
+            li.setAttribute('data-lat', d.lat);
+            li.setAttribute('data-dist', d.dist);
+            var pct = Math.floor((d.z - minZ) * 100 / diff);
+            li.setAttribute('class', 'percent v' + pct);
+            li.title = 'altitude : ' + d.z + 'm';
+            li.setAttribute('style', 'width: ' + barwidth + '%');
+            ul.appendChild(li);
+        }
+        var divX = document.createElement('div');
+        divX.className = 'x-title-horizontal';
+        divX.innerHTML = dist + ' km';
+        div.appendChild(divX);
+        context._profile = container;
+    };
+    ElevationPath.DISPLAY_PROFILE_RAW = function (data, container, context) {
+        if (container) {
+            while (container.firstChild) {
+                container.removeChild(container.firstChild);
+            }
+        }
+        var div = document.createElement('textarea');
+        div.id = 'profilElevationResults';
+        div.rows = 10;
+        div.cols = 50;
+        div.style.width = '100%';
+        div.innerHTML = JSON.stringify(data, undefined, 4);
+        container.appendChild(div);
+        context._profile = container;
+    };
+    ElevationPath.DISPLAY_PROFILE_LIB_D3 = function (data, container, context) {
+        if (typeof d3 === 'undefined') {
+            console.log('Lib. D3 is not loaded !');
+            return;
+        }
+        if (container) {
+            while (container.firstChild) {
+                container.removeChild(container.firstChild);
+            }
+        }
+        var margin = {
+            top: 20,
+            right: 20,
+            bottom: 30,
+            left: 40
+        };
+        var width = container.clientWidth - margin.left - margin.right;
+        var height = container.clientHeight - margin.top - margin.bottom;
+        var x = d3.scale.linear().range([
+            0,
+            width
+        ]);
+        var y = d3.scale.linear().range([
+            height,
+            0
+        ]);
+        var xAxis = d3.svg.axis().scale(x).orient('bottom').ticks(5);
+        var yAxis = d3.svg.axis().scale(y).orient('left').ticks(5);
+        var line = d3.svg.line().interpolate('basis').x(function (d) {
+            return x(d.dist);
+        }).y(function (d) {
+            return y(d.z);
+        });
+        var area = d3.svg.area().interpolate('basis').x(function (d) {
+            return x(d.dist);
+        }).y0(height).y1(function (d) {
+            return y(d.z);
+        });
+        var svg = d3.select(container).append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom).append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
+        var xDomain = d3.extent(data, function (d) {
+            return d.dist;
+        });
+        x.domain(xDomain);
+        var yDomain = [
+            0,
+            d3.max(data, function (d) {
+                return d.z;
+            })
+        ];
+        y.domain(yDomain);
+        svg.append('path').datum(data).attr('class', 'area-d3').attr('d', area);
+        svg.append('g').attr('class', 'x axis-d3').attr('transform', 'translate(0,' + height + ')').call(xAxis).append('text').attr('y', -15).attr('dy', '.71em').attr('x', width).text('Distance (km)');
+        svg.append('g').attr('class', 'y axis-d3').call(yAxis).append('text').attr('transform', 'rotate(-90)').attr('y', 6).attr('dy', '.71em').text('Altitude (m)');
+        svg.append('g').attr('class', 'grid-d3 vertical').attr('transform', 'translate(0,' + height + ')').call(xAxis.orient('bottom').tickSize(-height, 0, 0).tickFormat(''));
+        svg.append('g').attr('class', 'grid-d3 horizontal').call(yAxis.orient('left').tickSize(-width, 0, 0).tickFormat(''));
+        svg.append('path').datum(data).attr('class', 'line-d3').attr('d', line);
+        svg.selectAll('circle').data(data).enter().append('circle').attr('cx', function (d) {
+            return x(d.dist);
+        }).attr('cy', function (d) {
+            return y(d.z);
+        }).attr('r', 0).attr('class', 'circle-d3');
+        var focus = svg.append('g').style('display', 'none');
+        focus.append('line').attr('id', 'focusLineX').attr('class', 'focusLine-d3');
+        focus.append('line').attr('id', 'focusLineY').attr('class', 'focusLine-d3');
+        focus.append('circle').attr('id', 'focusCircle').attr('r', 4).attr('class', 'circle-d3 focusCircle-d3');
+        var div = d3.select(container).append('div').attr('class', 'tooltip-d3').style('opacity', 0);
+        var bisectDist = d3.bisector(function (d) {
+            return d.dist;
+        }).left;
+        var self = this;
+        var map = context._map;
+        svg.append('rect').attr('class', 'overlay-d3').attr('width', width).attr('height', height).on('mouseover', function () {
+            focus.style('display', null);
+            self._marker = L.marker(L.latLng(data[0].lat, data[0].lon), {
+                icon: new IconDefault('orange'),
+                draggable: false,
+                clickable: false,
+                zIndexOffset: 1000
+            });
+            self._marker.addTo(map);
+        }).on('mouseout', function () {
+            focus.style('display', 'none');
+            if (self._marker) {
+                map.removeLayer(self._marker);
+                self._marker = null;
+            }
+            div.transition().duration(500).style('opacity', 0);
+        }).on('mousemove', function () {
+            var m = d3.mouse(this);
+            var distance = x.invert(m[0]);
+            var i = bisectDist(data, distance);
+            var d0 = data[i - 1];
+            var d1 = data[i];
+            var d = distance - d0[0] > d1[0] - distance ? d1 : d0;
+            var xc = x(d.dist);
+            var yc = y(d.z);
+            focus.select('#focusCircle').attr('cx', xc).attr('cy', yc);
+            focus.select('#focusLineX').attr('x1', xc).attr('y1', y(yDomain[0])).attr('x2', xc).attr('y2', y(yDomain[1]));
+            focus.select('#focusLineY').attr('x1', x(xDomain[0])).attr('y1', yc).attr('x2', x(xDomain[1])).attr('y2', yc);
+            self._marker.setLatLng(L.latLng(d.lat, d.lon));
+            self._marker.update();
+            div.transition().duration(200).style('opacity', 0.9);
+            div.html('Alt : ' + d.z + ' m <br/>' + 'Lon : ' + d.lon + ' <br/>' + 'Lat : ' + d.lat).style('left', d3.event.pageX + 'px').style('top', d3.event.pageY - 28 + 'px');
+        });
+        context._profile = d3.selectAll('rect.overlay')[0][0];
+    };
+    ElevationPath.DISPLAY_PROFILE_LIB_AMCHARTS = function (data, container, context) {
+        if (typeof AmCharts === 'undefined') {
+            console.log('Lib. AmCharts is not loaded !');
+            return;
+        }
+        AmCharts.addInitHandler(function () {
+        });
+        context._profile = AmCharts.makeChart(container, {
+            type: 'serial',
+            pathToImages: 'http://cdn.amcharts.com/lib/3/images/',
+            categoryField: 'dist',
+            autoMarginOffset: 0,
+            marginRight: 10,
+            marginTop: 10,
+            startDuration: 0,
+            color: '#5E5E5E',
+            fontSize: 10,
+            theme: 'light',
+            thousandsSeparator: '',
+            categoryAxis: {
+                color: '#5E5E5E',
+                gridPosition: 'start',
+                minHorizontalGap: 40,
+                tickPosition: 'start',
+                title: 'Distance (km)',
+                titleColor: '#5E5E5E',
+                startOnAxis: true
+            },
+            chartCursor: {
+                animationDuration: 0,
+                bulletsEnabled: true,
+                bulletSize: 10,
+                categoryBalloonEnabled: false,
+                cursorColor: '#F90',
+                graphBulletAlpha: 1,
+                graphBulletSize: 1,
+                zoomable: false
+            },
+            trendLines: [],
+            graphs: [{
+                    balloonColor: '#CCCCCC',
+                    balloonText: '<span class=\'altiPathValue\'>[[title]] : [[value]]m</span><br/><span class=\'altiPathCoords\'>(lat: [[lat]] / lon:[[lon]])</span>',
+                    bullet: 'round',
+                    bulletAlpha: 0,
+                    bulletBorderColor: '#FFF',
+                    bulletBorderThickness: 2,
+                    bulletColor: '#F90',
+                    bulletSize: 6,
+                    hidden: false,
+                    id: 'AmGraph-1',
+                    fillAlphas: 0.4,
+                    fillColors: '#C77A04',
+                    lineAlpha: 1,
+                    lineColor: '#C77A04',
+                    lineThickness: 1,
+                    title: 'Altitude',
+                    valueField: 'z'
+                }],
+            guides: [],
+            valueAxes: [{
+                    id: 'ValueAxis-1',
+                    minVerticalGap: 20,
+                    title: 'Altitude (m)'
+                }],
+            allLabel: [],
+            balloon: {
+                borderColor: '#CCCCCC',
+                borderThickness: 1,
+                fillColor: '#FFFFFF',
+                showBullet: true
+            },
+            titles: [],
+            dataProvider: data
+        });
+        var _initPosition = data[0];
+        context._activateProfilEvent(_initPosition);
+    };
+    return ElevationPath;
+}(leaflet, leafletDraw, {}, gp, CommonUtilsCheckRightManagement, CommonUtilsSelectorID, LeafletControlsLocationSelector, LeafletControlsUtilsPositionFormater, LeafletControlsUtilsIconDefault, CommonControlsElevationPathDOM);
+LeafletControlsLogo = function (L) {
+    var Logo = L.Control.extend({
+        options: {
+            position: 'topright',
+            picto: null,
+            url: null,
+            text: null,
+            size: '30px'
+        },
+        initialize: function (options) {
+            L.setOptions(this, options);
+        },
+        onAdd: function () {
+            var container = L.DomUtil.create('div', 'gp-control-logo', container);
+            var bLink = this.options.url || this.options.text ? true : false;
+            var link = null;
+            if (bLink) {
+                link = L.DomUtil.create('a', '', container);
+                link.target = '_blank';
+                if (this.options.url) {
+                    link.href = this.options.url;
+                    this.options.text ? link.title = this.options.text : null;
+                }
+            }
+            if (bLink && this.options.text) {
+                link.text = this.options.text;
+            }
+            var bImage = this.options.picto ? true : false;
+            var image = null;
+            if (bImage) {
+                if (bLink) {
+                    image = L.DomUtil.create('img', '', link);
+                } else {
+                    image = L.DomUtil.create('img', '', container);
+                }
+                image.src = this.options.picto;
+                if (typeof this.options.size === 'string') {
+                    image.style.height = image.style.width = this.options.size;
+                } else {
+                    image.style.height = this.options.size.height;
+                    image.style.width = this.options.size.width;
+                }
+            }
+            return container;
+        }
+    });
+    return Logo;
+}(leaflet);
+LeafletControlsControls = function (LayerSwitcher, Isocurve, MousePosition, ReverseGeocoding, Route, SearchEngine, ElevationPath, Logo) {
+    var Controls = {
+        LayerSwitcher: function (options) {
+            return new LayerSwitcher(options);
+        },
+        Isocurve: function (options) {
+            return new Isocurve(options);
+        },
+        MousePosition: function (options) {
+            return new MousePosition(options);
+        },
+        ReverseGeocode: function (options) {
+            return new ReverseGeocoding(options);
+        },
+        Route: function (options) {
+            return new Route(options);
+        },
+        SearchEngine: function (options) {
+            return new SearchEngine(options);
+        },
+        ElevationPath: function (options) {
+            return new ElevationPath(options);
+        },
+        Logo: function (options) {
+            return new Logo(options);
+        }
+    };
+    return Controls;
+}(LeafletControlsLayerSwitcher, LeafletControlsIsocurve, LeafletControlsMousePosition, LeafletControlsReverseGeocoding, LeafletControlsRoute, LeafletControlsSearchEngine, LeafletControlsElevationPath, LeafletControlsLogo);
+CommonUtilsLayerUtils = function () {
+    var LayerUtils = {
+        getZoomLevelFromScaleDenominator: function (scaleDenominator, crs) {
+            var resolutionsNatives = {};
+            switch (crs) {
+            case 'EPSG:2154':
+                resolutionsNatives = {
+                    0: 104579.224549894,
+                    1: 52277.5323537905,
+                    2: 26135.4870785954,
+                    3: 13066.8913818,
+                    4: 6533.2286041135,
+                    5: 3266.5595244627,
+                    6: 1633.2660045974,
+                    7: 816.629554986,
+                    8: 408.3139146768,
+                    9: 204.1567415109,
+                    10: 102.0783167832,
+                    11: 51.0391448966,
+                    12: 25.5195690743,
+                    13: 12.7597836936,
+                    14: 6.379891636,
+                    15: 3.1899457653,
+                    16: 1.5949728695,
+                    17: 0.7974864315,
+                    18: 0.3987432149,
+                    19: 0.1993716073,
+                    20: 0.0996858037,
+                    21: 0.0498429018
+                };
+                break;
+            default:
+                resolutionsNatives = {
+                    0: 156543.033928041,
+                    1: 78271.51696402048,
+                    2: 39135.758482010235,
+                    3: 19567.87924100512,
+                    4: 9783.93962050256,
+                    5: 4891.96981025128,
+                    6: 2445.98490512564,
+                    7: 1222.99245256282,
+                    8: 611.49622628141,
+                    9: 305.7481131407048,
+                    10: 152.8740565703525,
+                    11: 76.43702828517624,
+                    12: 38.21851414258813,
+                    13: 19.10925707129406,
+                    14: 9.554628535647032,
+                    15: 4.777314267823516,
+                    16: 2.388657133911758,
+                    17: 1.194328566955879,
+                    18: 0.5971642834779395,
+                    19: 0.2985821417389697,
+                    20: 0.1492910708694849,
+                    21: 0.0746455354347424
+                };
+                break;
+            }
+            var resolution = scaleDenominator * 0.00028;
+            for (var index in resolutionsNatives) {
+                if (resolutionsNatives.hasOwnProperty(index)) {
+                    if (resolutionsNatives[index] <= resolution) {
+                        return index;
+                    }
+                }
+            }
+            return 0;
+        },
+        getAttributions: function (params) {
+            var zoom = params.zoom;
+            var attributions = [];
+            if (params.originators != null && params.visibility) {
+                var drawLogo;
+                for (var j = 0, jl = params.originators.length; j < jl; j++) {
+                    drawLogo = true;
+                    var originator = params.originators[j];
+                    var constraints = params.originators[j].constraints || [];
+                    for (var k = 0, kl = constraints.length; k < kl; k++) {
+                        var constraint = constraints[k];
+                        drawLogo = true;
+                        var minZoomLevel = this.getZoomLevelFromScaleDenominator(constraint.maxScaleDenominator, params.crs);
+                        var maxZoomLevel = this.getZoomLevelFromScaleDenominator(constraint.minScaleDenominator, params.crs);
+                        if (minZoomLevel && minZoomLevel > zoom) {
+                            drawLogo = false;
+                        }
+                        if (drawLogo && maxZoomLevel && maxZoomLevel < zoom) {
+                            drawLogo = false;
+                        }
+                        var bbox = constraint.bbox;
+                        if (drawLogo && bbox) {
+                            drawLogo = false;
+                            var viewExtent = params.extent;
+                            if (viewExtent) {
+                                var bounds = [
+                                    bbox.top,
+                                    bbox.left,
+                                    bbox.bottom,
+                                    bbox.right
+                                ];
+                                if (this.intersects(viewExtent, bounds)) {
+                                    drawLogo = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    if (drawLogo) {
+                        var logo = originator.logo;
+                        var url = originator.url;
+                        var name = originator.name ? originator.name : '';
+                        var text = originator.attribution;
+                        var container = document.createElement('div');
+                        container.className = 'gp-control-attribution';
+                        var link = null;
+                        link = document.createElement('a');
+                        link.className = 'gp-control-attribution-link';
+                        link.target = '_blank';
+                        container.appendChild(link);
+                        if (url) {
+                            link.href = url;
+                        }
+                        var bImage = logo ? true : false;
+                        var image = null;
+                        if (bImage) {
+                            image = document.createElement('img');
+                            if (link) {
+                                image.className = 'gp-control-attribution-image';
+                                link.appendChild(image);
+                            } else {
+                                image.className = '';
+                                container.appendChild(image);
+                            }
+                            image.src = logo;
+                            image.title = text || name;
+                            image.style.height = '30px';
+                            image.style.width = '30px';
+                        } else {
+                            if (name) {
+                                link.textContent = name;
+                            } else if (text) {
+                                link.textContent = text;
+                            } else if (url) {
+                                link.textContent = url;
+                            } else {
+                                link.textContent = '';
+                            }
+                        }
+                        attributions.push(container.innerHTML + ' ');
+                    }
+                }
+            }
+            return attributions;
+        },
+        intersects: function (extent1, extent2) {
+            var intersectsX = extent1[1] <= extent2[3] && extent2[1] <= extent1[3];
+            var intersectsY = extent1[2] <= extent2[0] && extent2[2] <= extent1[0];
+            return intersectsX && intersectsY;
+        }
+    };
+    return LayerUtils;
+}();
+LeafletLayersLayerConfig = function (woodman, Config, Util) {
+    var LayerConfig = {
+        get: function (options) {
+            var params = {};
+            if (!Config.isConfigLoaded()) {
+                return;
+            }
+            params = Config.getLayerParams(options.layer, options.service, options.key);
+            if (!params) {
+                return;
+            }
+            params.minZoom = Util.getZoomLevelFromScaleDenominator(params.maxScale) || 1;
+            params.maxZoom = Util.getZoomLevelFromScaleDenominator(params.minScale) || 21;
+            return params;
+        }
+    };
+    return LayerConfig;
+}({}, CommonUtilsConfig, CommonUtilsLayerUtils);
+LeafletLayersLayerEvent = function (woodman, LayerUtil) {
+    var LayerEvent = {
+        _id: null,
+        _attributions: [],
+        _visibility: true,
+        _originators: [],
+        isEnable: function (map) {
+            if (!map.attributionControl) {
+                return false;
+            }
+            return true;
+        },
+        setVisible: function (visibility) {
+            this._visibility = visibility;
+        },
+        getVisible: function () {
+            return this._visibility;
+        },
+        _onRemoveLayer: function (e) {
+            if (e.layer._geoportal_id != this._geoportal_id) {
+                return;
+            }
+            this.setVisible(false);
+        },
+        _onAddLayer: function (e) {
+            if (e.layer._geoportal_id != this._geoportal_id) {
+                return;
+            }
+            this.setVisible(true);
+        },
+        _onMoveEndLayer: function (e) {
+            this.updateAttributions(this._map, this);
+        },
+        updateAttributions: function (map) {
+            if (!this.isEnable(map)) {
+                return;
+            }
+            this.removeAttributions(map);
+            this.addAttributions(map);
+        },
+        removeAttributions: function (map) {
+            if (!this.isEnable(map)) {
+                return;
+            }
+            for (var i = 0; i < this._attributions.length; i++) {
+                map.attributionControl.removeAttribution(this._attributions[i]);
+            }
+            if (this._attributions) {
+                this._attributions = [];
+            }
+        },
+        addAttributions: function (map) {
+            if (!this.isEnable(map)) {
+                return;
+            }
+            var topLeft = map.getBounds().getNorthWest();
+            var bottomRight = map.getBounds().getSouthEast();
+            var arrayBounds = [
+                topLeft.lat,
+                topLeft.lng,
+                bottomRight.lat,
+                bottomRight.lng
+            ];
+            var params = {
+                extent: arrayBounds,
+                zoom: map.getZoom(),
+                originators: this._originators,
+                visibility: this._visibility
+            };
+            var attributionsOriginators = LayerUtil.getAttributions(params);
+            if (attributionsOriginators && attributionsOriginators.length !== 0) {
+                for (var i = 0; i < attributionsOriginators.length; i++) {
+                    this._attributions.push(attributionsOriginators[i]);
+                    map.attributionControl.addAttribution(attributionsOriginators[i]);
+                }
+            }
+        }
+    };
+    return LayerEvent;
+}({}, CommonUtilsLayerUtils);
+LeafletLayersWMS = function (L, Gp, woodman, LayerEvent) {
+    var WMS = L.TileLayer.WMS.extend({
+        includes: LayerEvent,
+        initialize: function (url, options) {
+            var settings = {};
+            L.Util.extend(settings, options.paramsWms, options.paramsNative);
+            L.TileLayer.WMS.prototype.initialize.call(this, Gp.Helper.normalyzeUrl(url, { 'gp-leaflet-ext': '0.8.1' }, false), settings);
+            this._originators = options.originators;
+            this._legends = options.legends;
+            this._metadata = options.metadata;
+            this._title = options.title;
+            this._description = options.description;
+            this._quicklookUrl = options.quicklookUrl;
+            this._geoportal_id = 0;
+        },
+        onAdd: function (map) {
+            this._map = map;
+            this._geoportal_id = L.stamp(this);
+            L.TileLayer.WMS.prototype.onAdd.call(this, map);
+            this.setVisible(true);
+            this.updateAttributions(map);
+            map.on({
+                overlayremove: this._onRemoveLayer,
+                overlayadd: this._onAddLayer,
+                layerremove: this._onRemoveLayer,
+                layeradd: this._onAddLayer,
+                moveend: this._onMoveEndLayer
+            }, this);
+        },
+        onRemove: function (map) {
+            this._map = map;
+            L.TileLayer.prototype.onRemove.call(this, map);
+            this.setVisible(false);
+            this.removeAttributions(map);
+            map.off({
+                overlayremove: this._onRemoveLayer,
+                overlayadd: this._onAddLayer,
+                layerremove: this._onRemoveLayer,
+                layeradd: this._onAddLayer,
+                moveend: this._onMoveEndLayer
+            }, this);
+        },
+        getTileUrl: function (tilePoint) {
+            var lstProjEpsgGeographic = ['EPSG:4326'];
+            var map = this._map;
+            var tileSize = this.options.tileSize;
+            var nwPoint = tilePoint.multiplyBy(tileSize);
+            var sePoint = nwPoint.add([
+                tileSize,
+                tileSize
+            ]);
+            var nw = this._crs.project(map.unproject(nwPoint, tilePoint.z));
+            var se = this._crs.project(map.unproject(sePoint, tilePoint.z));
+            var bbox = this._wmsVersion >= 1.3 && lstProjEpsgGeographic.indexOf(this._crs.code) !== -1 ? [
+                se.y,
+                nw.x,
+                nw.y,
+                se.x
+            ].join(',') : [
+                nw.x,
+                se.y,
+                se.x,
+                nw.y
+            ].join(',');
+            var url = L.Util.template(this._url, { s: this._getSubdomain(tilePoint) });
+            return url + L.Util.getParamString(this.wmsParams, url, true) + '&BBOX=' + bbox;
+        }
+    });
+    return WMS;
+}(leaflet, gp, {}, LeafletLayersLayerEvent);
+LeafletLayersWMTS = function (L, Gp, woodman, LayerEvent) {
+    var WMTS = L.TileLayer.extend({
+        includes: LayerEvent,
+        defaultWmtsParams: {
+            service: 'WMTS',
+            request: 'GetTile',
+            version: '1.0.0',
+            layer: '',
+            style: '',
+            tilematrixset: 'PM',
+            format: 'image/jpeg'
+        },
+        initialize: function (url, options) {
+            this._wmtsParams = {};
+            L.Util.extend(this._wmtsParams, this.defaultWmtsParams, options.paramsWmts);
+            L.TileLayer.prototype.initialize.call(this, Gp.Helper.normalyzeUrl(url, { 'gp-leaflet-ext': '0.8.1' }, false), options.paramsNative);
+            this._originators = options.originators;
+            this._legends = options.legends;
+            this._metadata = options.metadata;
+            this._title = options.title;
+            this._description = options.description;
+            this._quicklookUrl = options.quicklookUrl;
+            this._geoportal_id = 0;
+        },
+        onAdd: function (map) {
+            this._map = map;
+            this._geoportal_id = L.stamp(this);
+            L.TileLayer.prototype.onAdd.call(this, map);
+            this.setVisible(true);
+            this.updateAttributions(map);
+            map.on({
+                overlayremove: this._onRemoveLayer,
+                overlayadd: this._onAddLayer,
+                layerremove: this._onRemoveLayer,
+                layeradd: this._onAddLayer,
+                moveend: this._onMoveEndLayer
+            }, this);
+        },
+        onRemove: function (map) {
+            this._map = map;
+            L.TileLayer.prototype.onRemove.call(this, map);
+            this.setVisible(false);
+            this.removeAttributions(map);
+            map.off({
+                overlayremove: this._onRemoveLayer,
+                overlayadd: this._onAddLayer,
+                layerremove: this._onRemoveLayer,
+                layeradd: this._onAddLayer,
+                moveend: this._onMoveEndLayer
+            }, this);
+        },
+        getTileUrl: function (tilePoint) {
+            var zoom = this._getZoomForUrl();
+            var url = L.Util.template(this._url, { s: this._getSubdomain(tilePoint) });
+            return url + L.Util.getParamString(this._wmtsParams, url) + '&tilematrix=' + zoom + '&tilerow=' + tilePoint.y + '&tilecol=' + tilePoint.x;
+        },
+        setParams: function (params, noRedraw) {
+            L.extend(this._wmtsParams, params);
+            if (!noRedraw) {
+                this.redraw();
+            }
+            return this;
+        }
+    });
+    return WMTS;
+}(leaflet, gp, {}, LeafletLayersLayerEvent);
+LeafletLayersLayers = function (L, woodman, LayerConfig, WMS, WMTS) {
+    var Layers = {
+        options: {},
+        params: {},
+        serviceUrl: 'http://localhost?no-rights-found-for=[{layer}]',
+        _initLogger: function () {
+        },
+        _initOptions: function () {
+            if (!this.options || Object.keys(this.options) === 0) {
+                throw new Error('PARAM_MISSING : options !');
+            }
+            if (!this.options.layer) {
+                throw new Error('PARAM_MISSING : layer !');
+            }
+            if (!this.options.apiKey) {
+                console.log('PARAM_MISSING : apiKey !');
+            }
+        },
+        _initParams: function (service) {
+            if (!service) {
+                service = 'WMTS';
+            }
+            this.params = LayerConfig.get({
+                key: this.options.apiKey,
+                layer: this.options.layer,
+                service: service
+            });
+            if (!this.params || Object.keys(this.params) === 0) {
+                this.params = {};
+                if (!this.options.apiKey) {
+                    console.log('WARNING PARAM_MISSING : parameter \'apiKey\' is mandatory if the contract key configuration has not been loaded !');
+                }
+            }
+        },
+        WMS: function (options, settings) {
+            this._initLogger();
+            this.options = options || {};
+            this._initOptions();
+            this.settings = settings || {};
+            this._initParams('WMS');
+            var serviceUrl = null;
+            if (this.params.key || this.options.apiKey) {
+                serviceUrl = this.params.url || L.Util.template('http://wxs.ign.fr/{key}/geoportail/r/wms', { key: this.params.key || this.options.apiKey });
+            } else {
+                serviceUrl = L.Util.template(this.serviceUrl, { layer: this.options.layer });
+            }
+            var paramsWms = {
+                layers: this.options.layer,
+                styles: this.params.styles || 'normal',
+                format: this.params.format || 'image/jpeg',
+                version: this.params.version || '1.3.0'
+            };
+            var paramsNative = {
+                minZoom: this.params.minZoom || 1,
+                maxZoom: this.params.maxZoom || 21
+            };
+            L.Util.extend(paramsNative, this.settings);
+            return new WMS(serviceUrl, {
+                paramsNative: paramsNative,
+                paramsWms: paramsWms,
+                originators: this.params.originators || [],
+                legends: this.params.legends || [],
+                metadata: this.params.metadata || [],
+                title: this.params.title || null,
+                description: this.params.description || null,
+                quicklookUrl: this.params.quicklookUrl || null
+            });
+        },
+        WMTS: function (options, settings) {
+            this._initLogger();
+            this.options = options || {};
+            this._initOptions();
+            this.settings = settings || {};
+            this._initParams('WMTS');
+            var serviceUrl = null;
+            if (this.params.key || this.options.apiKey) {
+                serviceUrl = this.params.url || L.Util.template('http://wxs.ign.fr/{key}/geoportail/wmts', { key: this.params.key || this.options.apiKey });
+            } else {
+                serviceUrl = L.Util.template(this.serviceUrl, { layer: this.options.layer });
+            }
+            var paramsWmts = {
+                layer: this.options.layer,
+                style: this.params.styles || 'normal',
+                format: this.params.format || 'image/jpeg',
+                version: this.params.version || '1.0.0',
+                tilematrixset: this.params.TMSLink || 'PM'
+            };
+            var paramsNative = {
+                minZoom: this.params.minZoom || 1,
+                maxZoom: this.params.maxZoom || 21
+            };
+            L.Util.extend(paramsNative, this.settings);
+            return new WMTS(serviceUrl, {
+                paramsNative: paramsNative,
+                paramsWmts: paramsWmts,
+                originators: this.params.originators || [],
+                legends: this.params.legends || [],
+                metadata: this.params.metadata || [],
+                title: this.params.title || '',
+                description: this.params.description || '',
+                quicklookUrl: this.params.quicklookUrl || ''
+            });
+        }
+    };
+    return Layers;
+}(leaflet, {}, LeafletLayersLayerConfig, LeafletLayersWMS, LeafletLayersWMTS);
+LeafletGpPluginLeaflet = function (L, P, Gp, Controls, ElevationPath, Layers, CRS, Register) {
+    Gp.leafletExtVersion = '0.8.1';
+    Gp.leafletExtDate = '2016-12-02';
+    Gp.Register = Register;
+    L.geoportalLayer = Layers;
+    L.geoportalControl = Controls;
+    L.geoportalControl.ElevationPath.DISPLAY_PROFILE_LIB_D3 = ElevationPath.DISPLAY_PROFILE_LIB_D3;
+    L.geoportalControl.ElevationPath.DISPLAY_PROFILE_LIB_AMCHARTS = ElevationPath.DISPLAY_PROFILE_LIB_AMCHARTS;
+    L.geoportalControl.ElevationPath.DISPLAY_PROFILE_RAW = ElevationPath.DISPLAY_PROFILE_RAW;
+    L.geoportalControl.ElevationPath.DISPLAY_PROFILE_BY_DEFAULT = ElevationPath.DISPLAY_PROFILE_BY_DEFAULT;
+    L.geoportalCRS = CRS;
+    L.geoportalCRS.EPSG2154 = CRS.EPSG2154();
+    L.geoportalCRS.EPSG27572 = CRS.EPSG27572();
+    L.geoportalCRS.EPSG4326 = CRS.EPSG4326();
+    return Gp;
+}(leaflet, leafletDraw, gp, LeafletControlsControls, LeafletControlsElevationPath, LeafletLayersLayers, LeafletCRSCRS, CommonUtilsRegister);
+window.proj4 = proj4;
+
+return Gp;
+}));