diff --git a/frontend-js/src/main/js/ConfigurationType.js b/frontend-js/src/main/js/ConfigurationType.js index f43f816fe4ed9b93e69a7dff8a8f689d7927746b..0b85d8d10838ecdd82477b315eab0bdf5957a6cd 100644 --- a/frontend-js/src/main/js/ConfigurationType.js +++ b/frontend-js/src/main/js/ConfigurationType.js @@ -3,6 +3,7 @@ var ConfigurationType = { DEFAULT_MAP: "DEFAULT_MAP", GOOGLE_ANALYTICS_IDENTIFIER: "GOOGLE_ANALYTICS_IDENTIFIER", + GOOGLE_MAPS_API_KEY: "GOOGLE_MAPS_API_KEY", LOGO_IMG: "LOGO_IMG", LOGO_LINK: "LOGO_LINK", LEGEND_FILES: "LEGEND_FILES", diff --git a/frontend-js/src/main/js/Functions.js b/frontend-js/src/main/js/Functions.js index c2594abb1575f2dc79df84ec36093fc7b7c2b701..a61b0f35e20dbaa2ec3581d10ca3809eca06f2b4 100644 --- a/frontend-js/src/main/js/Functions.js +++ b/frontend-js/src/main/js/Functions.js @@ -299,4 +299,28 @@ Functions.distance = function(p1, el2) { return Math.sqrt(distToSegmentSquared(p1, el2.start, el2.end)); } }; + +Functions.loadScript = function (url) { + return new Promise(function (resolve) { + var scriptExists = false; + var scripts = document.getElementsByTagName('script'); + for (var i = scripts.length; i--;) { + if (scripts[i].src === url) + scriptExists = true; + } + if (!scriptExists) { + var head = document.getElementsByTagName('head')[0]; + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = url; + script.onload = function () { + resolve(); + }; + head.appendChild(script); + } else { + resolve(); + } + }); +}; + module.exports = Functions; diff --git a/frontend-js/src/main/js/minerva.js b/frontend-js/src/main/js/minerva.js index f84281272aa732bf0a147b5856f517e54f7e5425..9e976cfcfc93c0af10a99e19179a17b7e39c2a47 100644 --- a/frontend-js/src/main/js/minerva.js +++ b/frontend-js/src/main/js/minerva.js @@ -51,7 +51,7 @@ function processUrlGetParams(params) { } if (GuiConnector.getParams["search"] !== undefined) { var query = SearchDbOverlay.prototype.encodeQuery(AbstractDbOverlay.QueryType.SEARCH_BY_QUERY, - GuiConnector.getParams["search"]); + GuiConnector.getParams["search"]); sessionData.setSearchQuery(query); } @@ -59,76 +59,77 @@ function processUrlGetParams(params) { function insertGoogleAnalyticsCode() { return ServerConnector.getConfigurationParam(ConfigurationType.GOOGLE_ANALYTICS_IDENTIFIER).then( - function(identifier) { - if (identifier === "" || identifier === undefined || identifier === null) { - return; - } else { - global._gaq = global._gaq || []; - global._gaq.push([ '_setAccount', identifier ]); - global._gaq.push([ '_trackPageview' ]); - - (function() { - var ga = document.createElement('script'); - ga.type = 'text/javascript'; - ga.async = true; - ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') - + '.google-analytics.com/ga.js'; - var s = document.getElementsByTagName('script')[0]; - s.parentNode.insertBefore(ga, s); - })(); - return; - } - }); + function (identifier) { + if (identifier === "" || identifier === undefined || identifier === null) { + return; + } else { + global._gaq = global._gaq || []; + global._gaq.push(['_setAccount', identifier]); + global._gaq.push(['_trackPageview']); + + (function () { + var ga = document.createElement('script'); + ga.type = 'text/javascript'; + ga.async = true; + ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; + s.parentNode.insertBefore(ga, s); + })(); + return; + } + }); } + function createDivStructure(element) { var leftPanelDiv = functions.createElement({ - type : "div", - name : "leftPanelDiv", - className : "minerva-left-panel", + type: "div", + name: "leftPanelDiv", + className: "minerva-left-panel", }); element.appendChild(leftPanelDiv); var rightPanelDiv = functions.createElement({ - type : "div", - style : "display: table-cell;height:100%;width:100%;", + type: "div", + style: "display: table-cell;height:100%;width:100%;", }); element.appendChild(rightPanelDiv); var rightPanelContainerDiv = functions.createElement({ - type : "div", - style : "height:100%;width:100%;position:relative", + type: "div", + style: "height:100%;width:100%;position:relative", }); rightPanelDiv.appendChild(rightPanelContainerDiv); var menuDiv = functions.createElement({ - type : "div", - name : "menuDiv", - className : "menuBelt", + type: "div", + name: "menuDiv", + className: "menuBelt", }); rightPanelContainerDiv.appendChild(menuDiv); var mapDiv = functions.createElement({ - type : "div", - name : "mapDiv", - className : "mapClass", + type: "div", + name: "mapDiv", + className: "mapClass", }); rightPanelContainerDiv.appendChild(mapDiv); var legendDiv = functions.createElement({ - type : "div", - name : "legendDiv", - className : "minerva-legend", - style : "display:none", + type: "div", + name: "legendDiv", + className: "minerva-legend", + style: "display:none", }); rightPanelContainerDiv.appendChild(legendDiv); var contextMenu = functions.createElement({ - type : "ul", - name : "contextMenu", + type: "ul", + name: "contextMenu", }); element.appendChild(contextMenu); var selectionContextMenu = functions.createElement({ - type : "ul", - name : "selectionContextMenu", + type: "ul", + name: "selectionContextMenu", }); element.appendChild(selectionContextMenu); } @@ -136,28 +137,29 @@ function createDivStructure(element) { function getFullElements(customMap, identifiedElements) { var result = []; return Promise.each( - identifiedElements, - function(item) { - if (item.length === undefined) { - return customMap.getSubmapById(item.getModelId()).getModel().getByIdentifiedElement(item, true).then( - function(fullElement) { - result.push(fullElement); - }); - } else { - return getFullElements(customMap, item).then(function(resultRow) { - result.push(resultRow); + identifiedElements, + function (item) { + if (item.length === undefined) { + return customMap.getSubmapById(item.getModelId()).getModel().getByIdentifiedElement(item, true).then( + function (fullElement) { + result.push(fullElement); }); - } - }).then(function() { + } else { + return getFullElements(customMap, item).then(function (resultRow) { + result.push(resultRow); + }); + } + }).then(function () { return result; }); } + function getOverlayByName(customMap, dbOverlayName) { var dbOverlay = customMap.getOverlayByName(dbOverlayName); if (dbOverlay === null) { var validOverlays = ""; var overlays = customMap.getDbOverlays(); - for ( var overlay in overlays) { + for (var overlay in overlays) { if (overlays.hasOwnProperty(overlay)) { validOverlays += overlay.getName() + ", "; } @@ -175,18 +177,18 @@ function createMarkerElements(options) { var markerElements = []; if (params.length === undefined) { - params = [ params ]; + params = [params]; } for (var i = 0; i < params.length; i++) { var elementParam = params[i]; if (elementParam.type === undefined && isDefault) { markerElements.push({ - element : elementParam.element, + element: elementParam.element, }); } else if (elementParam.type === filteredType) { markerElements.push({ - element : elementParam.element, - options : elementParam.options, + element: elementParam.element, + options: elementParam.options, }); } else if (elementParam.type !== "ICON" && elementParam.type !== "SURFACE") { throw new Error("Unknown type:" + elementParam.type); @@ -209,14 +211,14 @@ function getElements(elementIdentifiers, customMap) { } var modelScopePromises = []; - for ( var key in elementsByModelId) { + for (var key in elementsByModelId) { if (elementsByModelId.hasOwnProperty(key)) { var model = customMap.getModel().getSubmodelById(parseInt(key)); modelScopePromises.push(model.getByIdentifiedElements(elementsByModelId[key], true)); } } // first promise fetch all data - return Promise.all(modelScopePromises).then(function() { + return Promise.all(modelScopePromises).then(function () { // this promise return result in the right order var elementPromises = []; for (var i = 0; i < identifiedElements.length; i++) { @@ -240,7 +242,7 @@ function getReactionsForElements(elementIdentifiers, customMap) { } var modelScopePromises = []; - for ( var key in elementsByModelId) { + for (var key in elementsByModelId) { if (elementsByModelId.hasOwnProperty(key)) { var model = customMap.getModel().getSubmodelById(parseInt(key)); var promise = model.getReactionsForElements(elementsByModelId[key], true); @@ -249,7 +251,7 @@ function getReactionsForElements(elementIdentifiers, customMap) { } // first promise fetch all data - return Promise.all(modelScopePromises).then(function(reactionResult) { + return Promise.all(modelScopePromises).then(function (reactionResult) { var result = []; for (var i = 0; i < reactionResult.length; i++) { result = result.concat(reactionResult[i]); @@ -260,27 +262,27 @@ function getReactionsForElements(elementIdentifiers, customMap) { function createResult(customMap) { return { - getVisibleDataOverlays : function() { + getVisibleDataOverlays: function () { return customMap.getVisibleDataOverlays(); }, - addListener : function(param) { + addListener: function (param) { var dbOverlay = getOverlayByName(customMap, param.dbOverlayName); - dbOverlay.addListener(param.type, function(e) { - return getFullElements(customMap, e.arg.identifiedElements).then(function(result) { + dbOverlay.addListener(param.type, function (e) { + return getFullElements(customMap, e.arg.identifiedElements).then(function (result) { return param.callback(result); }); }); }, - getHighlightedBioEntities : function(dbOverlayName) { + getHighlightedBioEntities: function (dbOverlayName) { if (dbOverlayName === undefined) { dbOverlayName = "user"; } var dbOverlay = getOverlayByName(customMap, dbOverlayName); var identifiedElements; - return dbOverlay.getIdentifiedElements().then(function(result) { + return dbOverlay.getIdentifiedElements().then(function (result) { identifiedElements = result; return getFullElements(customMap, identifiedElements); - }).then(function(fullElements) { + }).then(function (fullElements) { var result = []; for (var i = 0; i < identifiedElements.length; i++) { var type; @@ -290,12 +292,12 @@ function createResult(customMap) { type = "SURFACE"; } var row = { - element : fullElements[i], - type : type, - options : { - icon : identifiedElements[i].getIcon(), - color : identifiedElements[i].getColor(), - opacity : identifiedElements[i].getOpacity(), + element: fullElements[i], + type: type, + options: { + icon: identifiedElements[i].getIcon(), + color: identifiedElements[i].getColor(), + opacity: identifiedElements[i].getOpacity(), } }; result.push(row); @@ -303,19 +305,19 @@ function createResult(customMap) { return result; }); }, - getProject : function() { + getProject: function () { return customMap.getProject(); }, - getConfiguration : function() { + getConfiguration: function () { return ServerConnector.getConfiguration(); }, - getBioEntityById : function(param) { + getBioEntityById: function (param) { var isArray = true; if (param.length === undefined) { - param = [ param ]; + param = [param]; isArray = false; } - return getElements(param, customMap).then(function(result) { + return getElements(param, customMap).then(function (result) { if (!isArray) { return result[0]; } else { @@ -323,55 +325,55 @@ function createResult(customMap) { } }); }, - getReactionsWithElement : function(param) { + getReactionsWithElement: function (param) { if (param.length === undefined) { - param = [ param ]; + param = [param]; } return getReactionsForElements(param, customMap); }, - destroy : function() { - return leftPanel.destroy().then(function() { + destroy: function () { + return leftPanel.destroy().then(function () { customMap.destroy(); }); }, - showBioEntity : function(params) { + showBioEntity: function (params) { var iconElements = createMarkerElements({ - params : params, - filteredType : "ICON", - isDefault : true + params: params, + filteredType: "ICON", + isDefault: true }); var surfaceElements = createMarkerElements({ - params : params, - filteredType : "SURFACE", - isDefault : false + params: params, + filteredType: "SURFACE", + isDefault: false }); - return customMap.getOverlayByName("user").addMarker(iconElements).then(function() { + return customMap.getOverlayByName("user").addMarker(iconElements).then(function () { return customMap.getOverlayByName("user").addSurface(surfaceElements); }); }, - hideBioEntity : function(params) { + hideBioEntity: function (params) { var iconElements = createMarkerElements({ - params : params, - filteredType : "ICON", - isDefault : true + params: params, + filteredType: "ICON", + isDefault: true }); var surfaceElements = createMarkerElements({ - params : params, - filteredType : "SURFACE", - isDefault : false + params: params, + filteredType: "SURFACE", + isDefault: false }); - return customMap.getOverlayByName("user").removeMarker(iconElements).then(function() { + return customMap.getOverlayByName("user").removeMarker(iconElements).then(function () { return customMap.getOverlayByName("user").removeSurface(surfaceElements); }); }, - setCenter : function(params) { + setCenter: function (params) { var submap = customMap.getSubmapById(params.modelId); if (submap === null) { throw new Error("Unknown modelId: " + params.modelId); } return submap.setCenter(new google.maps.Point(params.x, params.y)); }, - fitBounds : function(params) { + fitBounds: function (params) { var submap = customMap.getSubmapById(params.modelId); if (submap === null) { throw new Error("Unknown modelId: " + params.modelId); @@ -385,7 +387,7 @@ function createResult(customMap) { bounds.extend(latLng2); return submap.getGoogleMap().fitBounds(bounds); }, - setZoom : function(params) { + setZoom: function (params) { var submap = customMap.getSubmapById(params.modelId); if (submap === null) { throw new Error("Unknown modelId: " + params.modelId); @@ -420,12 +422,12 @@ function verifyBrowser() { if (browser.name === "IE") { if (browser.version <= 8 || browser.compatibilityMode) { var message = "This webpage works only with Internet Explorer version 9 or greater.\n" - + "If you have Internet Explorer version 9 or greater and still see this message, please, turn the 'Compatibility modeoff:\n" - + "Open Internet Explorer and press the Alt key on your keyboard.\n" - + "Select 'Tools' menu item. \n" - + "Select the 'Compatibility View' settings option. \n" - + "Make sure the 'Display all websites in Compatibility View' check box is unchecked and that the 'Compatibility View; list of websites is cleared.\n" - + "\n" + "Alternatively, please, use other browsers: Chrome, Firefox or Safari."; + + "If you have Internet Explorer version 9 or greater and still see this message, please, turn the 'Compatibility modeoff:\n" + + "Open Internet Explorer and press the Alt key on your keyboard.\n" + + "Select 'Tools' menu item. \n" + + "Select the 'Compatibility View' settings option. \n" + + "Make sure the 'Display all websites in Compatibility View' check box is unchecked and that the 'Compatibility View; list of websites is cleared.\n" + + "\n" + "Alternatively, please, use other browsers: Chrome, Firefox or Safari."; GuiConnector.alert(message); } } @@ -441,7 +443,7 @@ function getProject(params) { function modifyParamsForTouchInterface(params) { if (params.markerOptimization === undefined && params.bigLogo === undefined - && params.customTouchInterface === undefined) { + && params.customTouchInterface === undefined) { var windowsTouchInterface = ((navigator.appVersion.indexOf("Win") > -1) && ('ontouchstart' in document.documentElement)); params.markerOptimization = !windowsTouchInterface; params.bigLogo = windowsTouchInterface; @@ -458,15 +460,17 @@ function create(params) { initGlobals(params); params.getElement().style.display = "table"; params.getElement().innerHTML = "<div style='vertical-align:middle;display:table-cell;text-align: center'>" - + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>"; + + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>"; // make sure that we are logged in - return ServerConnector.getToken().then(function() { + return ServerConnector.getToken().then(function () { return ServerConnector.getConfiguration(); - }).then(function(configuration) { + }).then(function (configuration) { params.setConfiguration(configuration); + return functions.loadScript("https://maps.google.com/maps/api/js?libraries=drawing&v=3.26&key=" + configuration.getOption(ConfigurationType.GOOGLE_MAPS_API_KEY)); + }).then(function () { return getProject(params); - }).then(function(project) { + }).then(function (project) { if (project === null) { var message = "Project with given id doesn't exist."; message += "<p>Please go to <a href='" + ServerConnector.getServerBaseUrl() + "'>default map</a>"; @@ -486,33 +490,33 @@ function create(params) { customMap = new CustomMap(params); new DbOverlayCollection({ - map : customMap + map: customMap }); leftPanel = new LeftPanel({ - element : functions.getElementByName(element, "leftPanelDiv"), - customMap : customMap + element: functions.getElementByName(element, "leftPanelDiv"), + customMap: customMap }); topMenu = new TopMenu({ - element : functions.getElementByName(element, "menuDiv"), - customMap : customMap + element: functions.getElementByName(element, "menuDiv"), + customMap: customMap }); legend = new Legend({ - element : functions.getElementByName(element, "legendDiv"), - customMap : customMap + element: functions.getElementByName(element, "legendDiv"), + customMap: customMap }); mapContextMenu = new MapContextMenu({ - element : functions.getElementByName(element, "contextMenu"), - customMap : customMap + element: functions.getElementByName(element, "contextMenu"), + customMap: customMap }); customMap.setContextMenu(mapContextMenu); selectionContextMenu = new SelectionContextMenu({ - element : functions.getElementByName(element, "selectionContextMenu"), - customMap : customMap + element: functions.getElementByName(element, "selectionContextMenu"), + customMap: customMap }); customMap.setSelectionContextMenu(selectionContextMenu); @@ -520,19 +524,19 @@ function create(params) { topMenu.setLeftPanel(leftPanel); return customMap.init(); - }).then(function() { + }).then(function () { return insertGoogleAnalyticsCode(customMap); - }).then(function() { + }).then(function () { return leftPanel.init(); - }).then(function() { + }).then(function () { return legend.init(); - }).then(function() { + }).then(function () { return topMenu.init(); - }).then(function() { + }).then(function () { return selectionContextMenu.init(); - }).then(function() { + }).then(function () { return mapContextMenu.init(); - }).then(function() { + }).then(function () { if (GuiConnector.getParams["layout"] !== undefined) { var layouts = params.getProject().getModel().getLayouts(); for (var j = 0; j < layouts.length; j++) { @@ -542,13 +546,13 @@ function create(params) { } } } - }).then(function() { + }).then(function () { var submapId = GuiConnector.getParams["submap"]; if (submapId !== undefined) { return customMap.openSubmap(submapId); } - }).then(function() { + }).then(function () { var result = createResult(customMap); if (params.isDebug()) { @@ -568,30 +572,32 @@ function createExport(params) { initGlobals(params); params.getElement().style.display = "table"; params.getElement().innerHTML = "<div style='vertical-align:middle;display:table-cell;text-align: center'>" - + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>"; + + "<img src='resources/images/icons/ajax-loader.gif'/>" + "</div>"; var result; // make sure that we are logged in - return ServerConnector.getToken().then(function() { + return ServerConnector.getToken().then(function () { return ServerConnector.getConfiguration(); - }).then(function(configuration) { + }).then(function (configuration) { params.setConfiguration(configuration); + return functions.loadScript("https://maps.google.com/maps/api/js?libraries=drawing&v=3.26&key=" + configuration.getOption(ConfigurationType.GOOGLE_MAPS_API_KEY)); + }).then(function () { return getProject(params); - }).then(function(project) { + }).then(function (project) { params.setProject(project); result = new Export(params); return result.init(); - }).then(function() { + }).then(function () { return result; }); } var minerva = { - create : create, - createExport : createExport, - ServerConnector : OriginalServerConnector, - GuiConnector : OriginalGuiConnector, - DualListbox : require('dual-listbox').DualListbox, + create: create, + createExport: createExport, + ServerConnector: OriginalServerConnector, + GuiConnector: OriginalGuiConnector, + DualListbox: require('dual-listbox').DualListbox, }; module.exports = minerva; diff --git a/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java b/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java index 8ff0f95344526a7e9e12cd455af360f510d71a1d..bf06ce4543ee61dc96e9bd0c093daf216820955a 100644 --- a/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java +++ b/model/src/main/java/lcsb/mapviewer/model/user/ConfigurationElementType.java @@ -131,7 +131,37 @@ public enum ConfigurationElementType { /** * Color used for undefined overlay values. */ - SIMPLE_COLOR_VAL("Overlay color when no values are defined", "00FF00", ConfigurationElementEditType.COLOR, false); + SIMPLE_COLOR_VAL("Overlay color when no values are defined", "00FF00", ConfigurationElementEditType.COLOR, false), + + /** + * Color used for 0 overlay value. + */ + NEUTRAL_COLOR_VAL("Don't touch [12.0.x compatibility]", "FFFFFF", ConfigurationElementEditType.COLOR, false), + + /** + * Opacity of data overlay objects in the frontend. + */ + OVERLAY_OPACITY("Don't touch [12.0.x compatibility]", "0.8", ConfigurationElementEditType.DOUBLE, false), + + /** + * Default content of the email when requesting for an account in the system. + */ + REQUEST_ACCOUNT_DEFAULT_CONTENT("Don't touch [12.0.x compatibility]", + "Dear Disease map team,\nI would like to request an account in the system.\nKind regards", + ConfigurationElementEditType.STRING, true), + + DEFAULT_VIEW_PROJECT("Don't touch [12.0.x compatibility]", "true", ConfigurationElementEditType.STRING, true), + + DEFAULT_EDIT_COMMENTS_PROJECT("Don't touch [12.0.x compatibility]", "false", ConfigurationElementEditType.STRING, + true), + + DEFAULT_LAYOUT_MANAGEMENT("Don't touch [12.0.x compatibility]", "false", ConfigurationElementEditType.STRING, true), + + SHOW_REACTION_TYPE("Don't touch [12.0.x compatibility]", "true", ConfigurationElementEditType.STRING, true), + + GOOGLE_MAPS_API_KEY("Google Maps API key", "", ConfigurationElementEditType.STRING, false), + + ; /** * Default value of the configuration parameter (it will be used only when diff --git a/web/src/main/webapp/index.xhtml b/web/src/main/webapp/index.xhtml index e1b4c892a031c5ef2ac1a77f9d6bf9f98cfa9a03..6ccfdf54fd788d78e692432ac9ff83cfb7752c1a 100644 --- a/web/src/main/webapp/index.xhtml +++ b/web/src/main/webapp/index.xhtml @@ -11,9 +11,6 @@ <h:head> - <!-- Google Maps API version 3.20 --> - <script src="https://maps.google.com/maps/api/js?libraries=drawing&v=3.26" type="text/javascript"/> - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" type="text/javascript"/> <script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.min.js" type="text/javascript"/> diff --git a/web/src/main/webapp/login.xhtml b/web/src/main/webapp/login.xhtml index 0f59d45952dded9f3f842730297bf43419f7fa14..109c6d5cf863d348471667d2f04539ec66180cb9 100644 --- a/web/src/main/webapp/login.xhtml +++ b/web/src/main/webapp/login.xhtml @@ -12,8 +12,6 @@ <link rel="shortcut icon" href="./resources/images/favicon.png" type="image/png"/> <ui:include src="/WEB-INF/components/admin/statistics.xhtml"/> - <script src="https://maps.google.com/maps/api/js?libraries=drawing&v=3.26" type="text/javascript"/> - <script src="https://code.jquery.com/jquery-1.12.1.min.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> @@ -38,9 +36,7 @@ minerva.GuiConnector.init(); minerva.ServerConnector.getSessionData(null); - minerva.ServerConnector.login().then(function () { - return minerva.ServerConnector.getProject() - }); + function login() { @@ -71,6 +67,16 @@ }); } }); + return minerva.ServerConnector.login().then(function () { + return minerva.ServerConnector.getConfiguration(); + }).then(function (configuration) { + + var head = document.getElementsByTagName('head')[0]; + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.src = "https://maps.google.com/maps/api/js?libraries=drawing&v=3.26&key=" + configuration.getOption("GOOGLE_MAPS_API_KEY"); + head.appendChild(script); + }); } //]]>